📑 题目:空结构体占不占内存空间? 为什么使用空结构体?

题目来源:映客

答案1:

空结构体是没有内存大小的结构体。
通过 unsafe.Sizeof() 可以查看空结构体的宽度,代码如下:

  1. var s struct{}
  2. fmt.Println(unsafe.Sizeof(s)) // prints 0

准确的来说,空结构体有一个特殊起点: zerobase 变量。zerobase是一个占用 8 个字节的uintptr全局变量。每次定义 struct {} 类型的变量,编译器只是把zerobase变量的地址给出去。也就是说空结构体的变量的内存地址都是一样的。
空结构体的使用场景主要有三种:

  • 实现方法接收者:在业务场景下,我们需要将方法组合起来,代表其是一个 ”分组“ 的,便于后续拓展和维护。
  • 实现集合类型:在 Go 语言的标准库中并没有提供集合(Set)的相关实现,因此一般在代码中我们图方便,会直接用 map 来替代:type Set map[string]struct{}
  • 实现空通道:在 Go channel 的使用场景中,常常会遇到通知型 channel,其不需要发送任何数据,只是用于协调 Goroutine 的运行,用于流转各类状态或是控制并发情况。

答案2:

  • 如果在两个不同的结构体类型之间进行比较(地址不同),则一定不能进行比较,除非强制转换成相同的结构体类型。
  • 如果在一个结构体中,需要看情况进行比较。在 Go 语言中,当其基本类型包含:slice、map、function 时,是不能比较的