在 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中文网其他相关文章!