首頁>技術>

獲取 slice 長度 #

透過前面關於 slice 的文章,我們知道了 slice header 的結構體定義:

1     2     3     4     5     6

// runtime/slice.go     type slice struct {         array unsafe.Pointer // 元素指標           len   int // 長度           cap   int // 容量     }

呼叫 make 函式新建一個 slice,底層呼叫的是 makeslice 函式,返回的是 slice 結構體:

1

func   makeslice(et *_type, len, cap int) slice

因此我們可以透過 unsafe.Pointer 和 uintptr 進行轉換,得到 slice 的欄位值。

1     2     3     4     5     6     7     8

func   main() {             s := make([]int, 9, 20)             var   Len = *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&s)) +   uintptr(8)))             fmt.Println(Len, len(s)) // 9 9

var   Cap = *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&s)) +   uintptr(16)))             fmt.Println(Cap, cap(s)) // 20 20     }

Len,cap 的轉換流程如下:

1     2

Len: &s => pointer => uintptr => pointer => *int => int     Cap: &s => pointer => uintptr => pointer   => *int => int

獲取 map 長度 #

再來看一下上篇文章我們講到的 map:

 1      2      3      4      5      6      7      8      9     10     11     12     13

type   hmap struct {             count     int             flags     uint8             B         uint8             noverflow uint16             hash0     uint32

buckets      unsafe.Pointer             oldbuckets   unsafe.Pointer             nevacuate  uintptr

extra *mapextra     }

和 slice 不同的是,makemap 函式返回的是 hmap 的指標,注意是指標:

1

func   makemap(t *maptype, hint int64, h *hmap, bucket unsafe.Pointer) *hmap

我們依然能透過 unsafe.Pointer 和 uintptr 進行轉換,得到 hamp 欄位的值,只不過,現在 count 變成二級指標了:

1     2     3     4     5     6     7     8

func   main() {             mp := make(map[string]int)             mp["qcrao"] = 100             mp["stefno"] = 18

count := **(**int)(unsafe.Pointer(&mp))             fmt.Println(count, len(mp)) // 2 2     }

count 的轉換過程:

1

&mp => pointer => **int => int

2
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • golang2021資料格式(94)unsafe修改私有成員