假设我有以下两个结构:
package main
import (
"fmt"
"unsafe"
)
type A struct {
int8
int16
bool
}
type B struct {
int8
bool
int16
}
func main() {
fmt.Println(unsafe.Sizeof(A{}), unsafe.Sizeof(B{})) // 6 4
}
的大小A
为6个字节。但是,大小B
为4个字节。
我以为它与它们在内存中的布局有关,但是我不确定我为什么理解它的行为。
编译器无法检测和优化吗?(重新排列字段顺序)
由于对齐导致填充。
对于数字类型,保证以下大小:
type size in bytes byte, uint8, int8 1 uint16, int16 2 uint32, int32, float32 4 uint64, int64, float64, complex64 8 complex128 16
保证以下最小对齐方式属性:
对于任何类型的变量x:unsafe.Alignof(x)至少为1。
对于结构类型的变量x:对于x的每个字段f,unsafe.Alignof(x)是所有值unsafe.Alignof(xf)中的最大值,但至少为1。
- 对于数组类型的变量x:unsafe.Alignof(x)与数组元素类型的变量的对齐方式相同。
如果结构或数组类型不包含大小大于零的字段(或元素),则其大小为零。两个不同的零大小变量在内存中可能具有相同的地址。
例如,
package main
import (
"fmt"
"unsafe"
)
type A struct {
x int8
y int16
z bool
}
type B struct {
x int8
y bool
z int16
}
func main() {
var a A
fmt.Println("A:")
fmt.Println("Size: ", unsafe.Sizeof(a))
fmt.Printf("Address: %p %p %p\n", &a.x, &a.y, &a.z)
fmt.Printf("Offset: %d %d %d\n", unsafe.Offsetof(a.x), unsafe.Offsetof(a.y), unsafe.Offsetof(a.z))
fmt.Println()
var b B
fmt.Println("B:")
fmt.Println("Size: ", unsafe.Sizeof(b))
fmt.Printf("Address: %p %p %p\n", &b.x, &b.y, &b.z)
fmt.Printf("Offset: %d %d %d\n", unsafe.Offsetof(b.x), unsafe.Offsetof(b.y), unsafe.Offsetof(b.z))
}
游乐场:https://play.golang.org/p/_8yDMungDg0
输出:
A:
Size: 6
Address: 0x10410020 0x10410022 0x10410024
Offset: 0 2 4
B:
Size: 4
Address: 0x10410040 0x10410041 0x10410042
Offset: 0 1 2
您可能正在匹配外部struct
语言,也许是另一种语言。由您决定告诉编译器您想要什么。编译器不会猜测。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句