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

}

感兴趣的可以试一下,这里也有在线环境:

https://go.dev/play/p/cldI9TWlYwZ

https://go.dev/play/p/oPfHrBZ8Gqg


Golang Go语言中 struct{} 的一个奇怪行为

更多关于Golang Go语言中 struct{} 的一个奇怪行为的实战教程也可以访问 https://www.itying.com/category-94-b0.html

11 回复

看一下反汇编代码就有答案了,这篇文章有详细说明: 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

因为标准已经说了可能相等也可能不等╮( ̄▽ ̄")╭

op 是不是前端转 go

在Go语言中,struct{} 是一种特殊的空结构体类型,它经常被用作占位符或者信号量,在某些场景下能带来意想不到的效果。然而,说 struct{} 有“奇怪行为”可能有些主观,让我们来探讨一下可能的误解或者不为人知的使用方式。

  1. 内存占用:空结构体不占用任何存储空间(除了可能的内存对齐开销),这是其高效之处。

  2. 作为占位符:在需要类型但不需要实际数据的情况下,struct{} 常被用作占位符,例如在map中作为键类型,或者在channel中传递信号。

  3. 比较:由于 struct{} 的所有实例在内存布局上都是相同的,因此它们之间的比较总是相等的。这在某些需要唯一标识但又不需要实际数据的场景下很有用。

  4. 性能优化:在一些高性能场景下,使用 struct{} 代替其他更复杂的数据结构可以减少内存分配和垃圾回收的压力。

如果你遇到的“奇怪行为”与上述点不符,可能是由以下原因造成的:

  • 误解了 struct{} 的语义或用法。
  • 与其他语言或Go的其他特性混淆。
  • 编译器或运行时环境的特定行为(尽管这种情况很少见)。

为了更具体地解决问题,建议提供具体的代码示例和观察到的行为描述,这样可以更准确地定位问题所在,并给出针对性的建议。

回到顶部