Golang中的unsafe.Sizeof()簡述
測試環境:
系統 win7 64位
go version: go1.10 windows/amd64
我們先看一下程式碼的輸出
package main import "unsafe" func main() { // string str1 := "abc" println("string1:", unsafe.Sizeof(str1)) // 16 str2 := "abcdef" println("string2:", unsafe.Sizeof(str2)) // 16 // 陣列 arr1 := [...]int{1, 2, 3, 4} println("array1:", unsafe.Sizeof(arr1)) // 32 = 8 * 4 arr2 := [...]int{1, 2, 3, 4, 5} println("array2:", unsafe.Sizeof(arr2)) // 40 = 8 * 5 // slice slice1 := []int{1, 2, 3, 4} println("slice1:", unsafe.Sizeof(slice1)) // 24 slice2 := []int{1, 2, 3, 4, 5} println("slice2:", unsafe.Sizeof(slice2)) // 24 slice3 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} println("slice3:", unsafe.Sizeof(slice3)) // 24 }
1、字串型別
為什麼字串的大小一直是16的,為什麼呢?
實際上字串型別對應一個結構體,該結構體有兩個域,第一個域是指向該字串的指標,第二個域是字串的長度,每個域佔8個位元組,但是並不包含指標指向的字串的內容,這也就是為什麼sizeof始終返回的是16。
組成可以理解成此結構體
typedef struct { char* buffer; size_tlen; } string;
2、陣列型別
編譯的時候系統自動,int的長度是由系統平臺來決定的,我用的是64位的系統,所以一個int就是 int64,每個數字佔用8個位元組,成員陣列元素個數正好等於輸出的值。
3、切片型別
看到切片和陣列還是有些不一樣的,我們看一下官方包的解釋 /src/unsafe/unsafe.go
// Sizeof takes an expression x of any type and returns the size in bytes
// of a hypothetical variable v as if v was declared via var v = x.
// The size does not include any memory possibly referenced by x.
// For instance, if x is a slice, Sizeof returns the size of the slice
// descriptor, not the size of the memory referenced by the slice.
意思是說如果是slice的話,則返回的是slice描述符的長度,而不是slice的記憶體長度,這裡輸出的長度是描述符的長度。