在 Go 中,聲明結構體欄位的順序會影響結構體的大小。為什麼?
type A struct { a bool b int64 c int } type B struct { b int64 a bool c int }
列印這些結構體的大小顯示:
fmt.Println(unsafe.Sizeof(A{})) // Output: 24 fmt.Println(unsafe.Sizeof(B{})) // Output: 16
即使它們具有相同的字段,但它們的大小不同。
欄位是否對齊或從特定位置開始記憶體位址取決於目標架構。例如,int64 需要 8 個位元組對齊。在A中,第一個欄位是bool,即1個位元組。為了正確對齊 b (int64),a 後面有一個 7 個位元組的隱式填充。
在 B 中,由於 a 後面跟著 int(4 位元組),因此只需要 3 個位元組的填充。這解釋了大小的差異。
// Offset (in bytes) for struct A fmt.Println(unsafe.Offsetof(a.a)) // Output: 0 fmt.Println(unsafe.Offsetof(a.b)) // Output: 8 fmt.Println(unsafe.Offsetof(a.c)) // Output: 16 // Offset for struct B fmt.Println(unsafe.Offsetof(b.b)) // Output: 0 fmt.Println(unsafe.Offsetof(b.a)) // Output: 8 fmt.Println(unsafe.Offsetof(b.c)) // Output: 12
type C struct {}
零大小結構的大小為零,表示沒有記憶體分配。儘管引用零大小結構的不同變量,它們可能共享相同的記憶體位址:
a := C{} b := C{} c := [0]int{} d := [3]C{} fmt.Printf("%p %p %p %p %p", &a, &b, &c, &d, &d[2])
輸出:
0x21cd7c 0x21cd7c 0x21cd7c 0x21cd7c 0x21cd7c
所有位址都是相同的,表明沒有為這些零分配記憶體-size 變數。
由於對齊要求和結構體字段排序會影響大小隱式填充。零大小結構透過不分配記憶體並可能為不同的變數共享相同的位址來優化記憶體使用。
以上是為什麼結構體字段順序會影響 Go 結構體的大小?的詳細內容。更多資訊請關注PHP中文網其他相關文章!