前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go语言中常见100问题-#65 Not using notification channels

Go语言中常见100问题-#65 Not using notification channels

作者头像
数据小冰
发布2022-08-15 15:24:46
1850
发布2022-08-15 15:24:46
举报
文章被收录于专栏:数据小冰
不要使用普通的通道发送通知,而应该使用chan struct{}

通道(channel)是一种通过信号在goroutine之间进行通信的机制。信号可以有数据也可以没有数据,但是对于Go开发者来说,处理没有数据的情况并不是那么简单。下面通过一个具体的例子来深入研究它,在程序中,会创建一个通道,该通道将在发生特定断开连接时发生通知,一种处理的思路是定义一个chan bool类型的通道。

代码语言:javascript
复制
disconnectCh := make(chan bool)

现在假设我们与这个通道的API进行交互,由于它是一个bool类型的通道,可以从里面接收真消息或假消息。如果收到true我们可能很清楚表达的含义是断开了连接,但是当收到false的时候,表达的是什么意思呢?表示的是我们没有断开连接吗?在这种情况下,多久我们将收到一次这样的信号?这是不是意味着我们已经进行了重新连接?也许,我们应该只期望收到为true的消息。

如果是上面这样的情况下,意味着我们不需要一个特定的值来传递信息,我们需要的是一个不需要发送数据的通道。这种通道有一种惯用方式是定义为chan struct{}类型。在Go语言中,空结构体struct{}不包含任何字段,无论在哪种计算机体系结构下,它占用的存储空间为零字节。可以使用unsafe.Sizeof进行验证,下面的程序执行结果输出0.

代码语言:javascript
复制
var s struct{}
fmt.Println(unsafe.Sizeof(s))

上面的程序打印输出结果如下

代码语言:javascript
复制
0

「NOTE: 也许有人好奇会问那为啥不使用空接口var i interface{}, 因为空接口占用的存储空间不是零字节。在32系统下,它占用8字节,在64位系统下,它占用16字节。」

事实上,在不关心值的时候,使用空结构体已成为一种标准用法。例如,当我们需要一个哈希结构时,只关心哈希的键不关心值,这个时候,我们应该使用一个空结构体作为值,例如map[string]struct{}

在使用通道的时候,如果我们想要创建一个通道来发送通知,并不发送数据。在Go中合适的方式是使用chan struct{}. 空结构体通道最广为人知的使用方式之一是在标准库context包。下面是从context包摘录的一个例子。

代码语言:javascript
复制
type Context interface {
 Deadline() (deadline time.Time, ok bool)
 Done() <-chan struct{}
 Err() error
 Value(key interface{}) interface{}
}

总结,一个通道可以有或没有数据,如果想设计一个符合Go标准惯用API, 在通道不传递实际数据的时候,我们应该将通道定义为chan struct{}类型。通过这种显示的定义方式,向接收者表明,他们不要期望消息内容有任何意义,只希望他们收到消息这一事实。这种类型的通道应该作为通知通道使用。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据小冰 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 不要使用普通的通道发送通知,而应该使用chan struct{}
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档