直接看代码
var i int32 var ii int64 var b bool var s string fmt.Printf("width:%d\n", unsafe.Sizeof(i)) // width:4 fmt.Printf("width:%d\n", unsafe.Sizeof(ii)) // width:8 fmt.Printf("width:%d\n", unsafe.Sizeof(b)) // width:1 fmt.Printf("width:%d\n", unsafe.Sizeof(s)) // width:16 { //空结构体的宽度为 0 type S struct{} var ss S fmt.Printf("width:%d\n", unsafe.Sizeof(ss)) // width:0 } { type stringStruct struct { str unsafe.Pointer // 8 len int // 8 } var ss stringStruct fmt.Printf("width:%d\n", unsafe.Sizeof(ss)) // width:16 } //以下涉及内存对齐 // https://dave.cheney.net/2014/03/25/the-empty-struct#comment-2815 { type S struct { a uint64 // 8 b uint32 // 4 } var s S fmt.Printf("width:%d\n", unsafe.Sizeof(s)) // width:16, not 12 } { type S struct { a uint64 // 8 b uint32 // 4 c [3]uint32 // 12 } var s S fmt.Printf("width:%d\n", unsafe.Sizeof(s)) // width:24 } { type S struct { a uint64 // 8 b bool //1 } var s S fmt.Printf("width:%d\n", unsafe.Sizeof(s)) // width:16, not 9 } { type S struct { a uint64 // 8 b uint32 // 4 c bool //1 d [3]uint32 // 12 } var s S fmt.Printf("width:%d\n", unsafe.Sizeof(s)) // width:32, not 25(8+4+1+12), not 28(8+4+4+12) } { type S struct { a uint64 // 8 b uint32 // 4 c bool //1 d uint32 // 4 } var s S fmt.Printf("width:%d\n", unsafe.Sizeof(s)) // width:24 }
关键要读懂Russ Cox的这段话:
It’s not true that “a value must be aligned in memory to a multiple of its width.” Each type has another property, its alignment. Alignments are always powers of two. The alignment of a basic type is usually equal to its width, but the alignment of a struct is the maximum alignment of any field, and the alignment of an array is the alignment of the array element. The maximum alignment of any value is therefore the maximum alignment of any basic type. Even on 32-bit systems this is often 8 bytes, because atomic operations on 64-bit values typically require 64-bit alignment.
To be concrete, a struct containing 3 int32 fields has alignment 4 but width 12.
It is true that a value’s width is always a multiple of its alignment. One implication is that there is no padding between array elements.
References:
https://dave.cheney.net/2014/03/25/the-empty-struct#comment-2815
https://ijayer.github.io/post/tech/code/golang/20200419_emtpy_struct_in_go