提供的代码演示了一个有趣的行为:
<br>A 型结构体{<pre class="brush:php;toolbar:false">a bool b int64 c int
}
type B struct {
b int64 a bool c int
}
打印大小时A{} 和 B{} 使用 unsafe.Sizeof,我们得到了令人惊讶的结果结果:
<br>fmt.Println(unsafe.Sizeof(A{})) // 输出:24<br>fmt.Println(unsafe.Sizeof(B{})) / / 输出: 16<br>
为什么这些结构体有不同的大小尽管有相同的字段?
答案在于字段对齐。在 Go 中,变量的地址必须根据其类型进行对齐,这种对齐对于 int64(8 字节对齐)等类型尤其重要。对于 A,第一个字段 a 是 bool,只需要 1 个字节的存储空间。在该字段之后,有一个 7 字节隐式填充,用于在 8 字节边界上对齐下一个字段 b(类型为 int64)。然而,在 B 的情况下,由于第一个字段 b 已经在 8 字节边界上对齐,因此不需要任何隐式填充,从而导致结构体大小更小,为 16 字节。
空结构的大小
继续,我们遇到另一个有趣的case:
<br>type C struct {<br>}<br>
打印 unsafe.Sizeof(C{}) 时,我们意外地得到的输出为 0。鉴于每个结构都占用一些空间,这怎么可能
Go 规范规定,没有大小大于零的字段或元素的结构体或数组的大小为零。它还意味着两个不同的零大小变量可以共享相同的内存地址。 C{} 就是这种情况,它的大小为零,可能不占用任何实际内存。相反,它可以引用与其他零大小值相同的内存地址,例如 struct{}{}、[]int{},甚至空数组 [3]struct{}{}。
理解字段对齐和零大小值的概念可以增强我们对 Go 内存管理的理解。通过在结构体中策略性地安排字段,我们可以优化内存分配并确保高效的数据操作。
以上是为什么具有相同字段的 Go 结构体具有不同的大小?的详细内容。更多信息请关注PHP中文网其他相关文章!