Skip to content

Latest commit

 

History

History
36 lines (22 loc) · 2.47 KB

9-5-Not-using-notification-channels.md

File metadata and controls

36 lines (22 loc) · 2.47 KB

9.5 不要使用布尔类型的通道

通道是一种通过信号在 goroutine 之间进行通信的机制。信号可以有或没有数据。然而,对于 Go 程序员来说,如何处理后一种情况并不总是直截了当的。

让我们用一个具体的例子来深入研究它。我们将创建一个通道,该通道将在发生特定断开连接时进行通知。一个想法可能是将其作为 chan bool 处理:

disconnectCh := make(chan bool)

现在,假设您与一个为您提供此类通道的 API 进行交互。由于它是一个布尔通道,我们可以接收真或假消息。可能很清楚 true 传达了什么。然而,false 是什么意思?这是否意味着我们没有断开连接,在这种情况下,我们多久会收到这样的信号?这是否意味着我们已经重新连接?我们甚至应该期望收到 false 吗?也许,我们应该只期望收到 true 的信息。

如果是这样的话,意味着我们不需要特定的值来传达一些信息,我们需要一个 不携带 数据的通道。

处理它的惯用方法是空结构的通道:chan struct{}

在 Go 中,空结构是没有任何字段的结构。无论架构如何,它都占用零字节的存储空间,我们可以使用 unsafe.Sizeof 进行验证:

var s struct{}
fmt.Println(unsafe.Sizeof(s))
0

Note 我们可能想知道为什么不使用空接口(var i interface{})。然而,一个空的接口实际上不是真的空。它在 32 位架构上占用 8 个字节,在 64 位架构 上占用 16 个字节。

空结构是传达缺乏意义的事实上的标准。例如,如果我们需要一个哈希集结构(唯一元素的集合),我们应该使用一个空结构作为值(例如,map[string]struct{})。

对于通道,如果我们想创建一个通道来发送没有数据的通知,在 Go 中合适的方式是 chan struct{}。空结构通道最广为人知的使用方式之一是 Go 上下文,我们将在本章中深入探讨。

一个通道可以有或没有数据。如果我们想设计一个符合 Go 标准的惯用 API,让我们记住一个没有数据的通道应该用 chan struct{} 类型表示。通过这种方式,它向接收者阐明了他们不期望消息内容有任何意义,只期望他们收到消息的事实。此类通道在 Go 通知通道中被调用。

在下一节中,让我们讨论 Go 如何处理 nil 通道以及使用它们的基本原理。