Golang Go语言中 struct{} 的一个奇怪行为
众所周知,golang 中有一个特殊的类型struct{}
,这个类型的变量不占用内存空间,也就是说下面两个变量 a 和 b 的地址相同。
func main() {
a := struct{}{}
b := struct{}{}
fmt.Printf("%p %p\n", &a, &b) // 输出 0x551090 0x551090
}
那么下面一段代码的输出也很合理:
func main() {
a := struct{}{}
b := struct{}{}
fmt.Printf("%p %p\n", &a, &b) // 输出 0x551090 0x551090
fmt.Println(&a == &b) // 输出 true
}
问题是下面这段代码,相比上一段代码只是去掉了第一个 fmt.Println ,a 和 b 地址竟然就不相等了?
func main() {
a := struct{}{}
b := struct{}{}
fmt.Println(&a == &b) // 输出 false
}
感兴趣的可以试一下,这里也有在线环境:
Golang Go语言中 struct{} 的一个奇怪行为
更多关于Golang Go语言中 struct{} 的一个奇怪行为的实战教程也可以访问 https://www.itying.com/category-94-b0.html
看一下反汇编代码就有答案了,这篇文章有详细说明: https://mp.weixin.qq.com/s/K5B2ItkzOb4eCFLxZI5Wvw
更多关于Golang Go语言中 struct{} 的一个奇怪行为的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
生成汇编看看?
真不愧是“大道至简”,gc 语言有(直接的)指针着实是糟糕的设计。
无关紧要
一般这么用:type a struct{}
定义一个新类型 ,然后到处用 a{},是相等的。
是否“奇怪”,主要看标准里有没有规定,如果没有规定就只是一种巧合,不能看作一种固定行为。
Pointers to distinct zero-size variables may or may not be equal.
https://go.dev/ref/spec
因为标准已经说了可能相等也可能不等╮( ̄▽ ̄")╭
在Go语言中,struct{}
是一种特殊的空结构体类型,它经常被用作占位符或者信号量,在某些场景下能带来意想不到的效果。然而,说 struct{}
有“奇怪行为”可能有些主观,让我们来探讨一下可能的误解或者不为人知的使用方式。
-
内存占用:空结构体不占用任何存储空间(除了可能的内存对齐开销),这是其高效之处。
-
作为占位符:在需要类型但不需要实际数据的情况下,
struct{}
常被用作占位符,例如在map中作为键类型,或者在channel中传递信号。 -
比较:由于
struct{}
的所有实例在内存布局上都是相同的,因此它们之间的比较总是相等的。这在某些需要唯一标识但又不需要实际数据的场景下很有用。 -
性能优化:在一些高性能场景下,使用
struct{}
代替其他更复杂的数据结构可以减少内存分配和垃圾回收的压力。
如果你遇到的“奇怪行为”与上述点不符,可能是由以下原因造成的:
- 误解了
struct{}
的语义或用法。 - 与其他语言或Go的其他特性混淆。
- 编译器或运行时环境的特定行为(尽管这种情况很少见)。
为了更具体地解决问题,建议提供具体的代码示例和观察到的行为描述,这样可以更准确地定位问题所在,并给出针对性的建议。