为什么在等待一些事情而不是`chan interface {}`时使用`chan struct {}`?

pee*_*rxu 2 go

在Golang,当我们需要等待完成某些事情时,我们将使用一个频道等待它完成.

例:

done := make(chan struct{})
go func() {
    // ...
    close(done)
}()
<-done
Run Code Online (Sandbox Code Playgroud)

但是,换句话说,chan interface{}在这种情况下工作正常.

那么,chan struct{}和之间有什么区别chan interface{}

例2:

done := make(chan struct{})
go func() {
    // ...
    done <- struct{}{}
}()
<- done
Run Code Online (Sandbox Code Playgroud)

在其他情况下,如果不关闭goroutine中的通道而不是发送对象.

将在goroutine中创建一个对象,但如果使用chan interface{},则可以将nil对象发送到通道.

相反,这是一个更好的方法chan struct{}吗?

Fli*_*mzy 12

在"完成"通道的示例中,从功能上讲,通道可以是任何类型,因为实际上没有数据被发送,并且通道仅用作信令机制.但是为了内存利用率,struct{}是Go中可用的最小数据类型,因为它几乎不包含任何内容,因此不需要分配,这就是它通常在这种情况下使用的原因.


Vol*_*ker 8

空结构struct {}不需要内存。make(chan bool, 1<<16)因此,如果您有一个大容量的通道,您可以通过从 切换到 来节省一些字节make(struct {}, 1<<16)。使用接口 {} 需要更多空间,这在这里确实很奇怪。

对于无缓冲的完成通道,我认为使用 struct {} 是错误的,因为它不清楚。使用简单chan bool的更明智。使用interface{}是完全错误的:它可能使用更多空间,甚至比struct{}更不清晰。

  • “stdlib 中的完成通道是 chan bool”——这不是一个普遍正确的说法。stdlib 中有许多用于完成通道的“chan struct{}”示例。但谢谢你的解释。 (6认同)
  • 我对你的最后一段感到困惑。对于无缓冲的完成通道来说,“struct{}”在什么意义上是错误的?那么“chan bool”如何更明智呢?`chan bool` 意味着您将通过通道发送 true 或 false 值,这是不正确的,所以对我来说这似乎是“错误的”。但我很想知道你的推理。 (4认同)
  • @Flimzy stdlib 中的 Done 通道是 chan bool ,即使您从不发送 false 或什至不发送任何内容而只是关闭通道,使用 chan bool 更自然。例如,chan struct{} 也不表示您从未打算发送任何内容。strcut {} 需要更多的输入和更多的阅读,尤其是一种具有特殊语义的罕见语言结构,因为 struct{} 的所有实例可能共享相同的内存位置。不太常见,更复杂,字符更多,不太清晰==&gt;错误。 (3认同)