\qquad 在 Go 语言中,空结构体 struct{} 是一种特殊的数据类型,它不包含任何字段或数据。虽然看起来不起眼,但它在某些场景下具有非常重要的作用。
1.0空结构体介绍
\qquad
空结构体 struct{} 不包含任何字段或数据,因此它不占用任何内存空间。这意味着在内存中创建空结构体的实例时,不会为其分配任何内存。这在某些场景下非常有用,特别是当我们只关注某个事件是否发生,而不关心具体的数据时。
\qquad
本文主要介绍两个struct{}的巧妙使用,常见与一些库的底层源码中,了解这些使用方法可以帮助快速理解源码中的相关使用。
- 信号传递:
<-chan struct{}
- 集合Set:
map[any]struct{}
1.1信号传递
众所周知golang中的chan类型可以实现协程的阻塞,使用类型为struct{}
的chan
,可以优雅的实现信号的传递,为了信号传递随意地向chan
中输入数据
var sign = make(chan struct{})
func run() {
go signAccepter()
time.Sleep(time.Second * 3)
fmt.Println("Closed")
// close(sign)
// 直接关闭也可以唤醒读操作
sign <- struct{}{}
}
func signAccepter() {
for {
select {
case <-sign:
fmt.Println("Running")
return
default:
}
}
}
func main() {
go run()
time.Sleep(20 * time.Second)
}
\qquad
值得一提的是,直接Close(chan)
,也可以唤醒阻塞中的<-chan
1.2 set集合
\qquad 通过将map中的value类型设置为struct{}类型,变相实现了key的集合
func main() {
set := make(map[string]struct{})
// 添加键到映射
set["key1"] = struct{}{}
set["key2"] = struct{}{}
// 检查键的存在性
if _, ok := set["key1"]; ok {
fmt.Println("Key1 exists")
}
// 删除键
delete(set, "key2")
// 检查键的存在性
if _, ok := set["key2"]; !ok {
fmt.Println("Key2 does not exist")
}
}