📑 题目:空结构体占不占内存空间? 为什么使用空结构体?
题目来源:映客
答案1:
空结构体是没有内存大小的结构体。
通过 unsafe.Sizeof() 可以查看空结构体的宽度,代码如下:
var s struct{}
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 时,是不能比较的