Golang中空struct指针比较结果异常原因咨询
Go中零大小struct实例比较结果随Printf调用变化的原因
先看你提供的代码:
package main import "fmt" func main() { type s struct{} s1 := new(s) s2 := new(s) // fmt.Printf("%p\n", s1) // fmt.Printf("%p\n", s2) fmt.Println(s1 == s2) }
这个现象的核心原因在于Go的变量逃逸分析和零大小类型的内存分配优化:
注释Printf时的情况
s1和s2是局部变量,编译器会将它们分配在栈上。尽管struct{}是零大小类型,但栈帧中会为每个变量保留一个逻辑占位位置,这导致s1和s2的栈地址并不相同,因此指针比较结果为false。取消注释Printf时的情况
fmt.Printf("%p", ...)需要接收指针参数,而且由于fmt.Printf是可变参数函数,编译器无法确定它不会长期持有这些指针,于是会将s1和s2标记为必须逃逸到堆上。而Go运行时对堆上的零大小类型实例有特殊优化:所有零大小实例会复用同一个内存地址(因为它们不需要实际存储空间),此时s1和s2指向同一个地址,指针比较结果自然为true。
需要注意的是,Go语言规范并没有强制要求零大小类型的所有实例地址必须相同,只是运行时在堆分配场景下会做复用优化;栈上的零大小变量地址则由栈帧布局决定,可能存在差异。
内容的提问来源于stack exchange,提问作者shaominyao
相关产品推荐
相关产品推荐

