普通变量
在go中通过unsafe.Sizeof可以获取go某种类型的字节数,有些类型是跟随系统的字长的,比如int、指针这些类型。
通过程序可以打印:
func TestVariable(t *testing.T) {
fmt.Printf("int size: %d\n", unsafe.Sizeof(int(0)))
fmt.Printf("int32 size: %d\n", unsafe.Sizeof(int32(0)))
fmt.Printf("int64 size: %d\n", unsafe.Sizeof(int64(0)))
i := 7
fmt.Printf("pointer size: %d\n", unsafe.Sizeof(&i))
}
//output:
int size: 8
int32 size: 4
int64 size: 8
pointer size: 8
空结构体
还有一种类型的大小是0,那就是空结构体。
如果大小是0字节,那么他有内存地址么?
答案是有的。
fmt.Printf("empty struct size: %d\n", unsafe.Sizeof(struct{}{}))
s1 := emptyStruct{}
s2 := emptyStruct{}
fmt.Printf("empty struct addr: %p\n", &s1)
fmt.Printf("empty struct addr: %p\n", &s2)
//output
empty struct size: 0
empty struct addr: 0x69ec20
empty struct addr: 0x69ec20
而且空结构体,在独立使用的时候,他的内存地址是固定的,在go中叫zerobase。
runtime/malloc.go
// base address for all 0-byte allocations
var zerobase uintptr
如果是在其他结构体中使用,他的地址是跟随结构体的,可以看到是跟zerobase完全不一样的一段地址。
type embedStruct struct {
field1 emptyStruct
field2 int32
}
func TestVariable(t *testing.T) {
s3 := embedStruct{}
fmt.Printf("empty struct addr: %p\n", &s3.field1)
}
//output
empty struct addr: 0xc000012328
使用场景:
主要目的就是节约内存,具体的可以
- 结合map使用,用作set
- 结合channel使用,用于信号通知