我有一个包含未初始化通道的结构。
当我向它写入内容时,该例程将按预期方式阻塞,但是永远不会通知读者管道中有东西。
我很惊讶没有错误,我想知道Go在做什么。
在下面的示例中,消息pushed和消息got it均未打印。(取消注释初始化,它将像超级按钮一样起作用)
pushed
got it
type MyStruct struct { over chan bool } func main() { nonInitialized := &MyStruct{} // nonInitialized.over = make(chan bool) go func() { for i := 0; i < 10; i++ { select { case <-nonInitialized.over: fmt.Println("got it") default: // proceed } fmt.Println("do some stuff") time.Sleep(10 * time.Millisecond) } panic("took too long") }() // push on the non initialized channel fmt.Println("pushing") nonInitialized.over <- true fmt.Println("pushed") }
这是操场https://play.golang.org/p/76zrCuoeoh
(我知道我应该初始化通道,这不是问题的目的,我想知道使用未初始化的通道在Go中发生了什么。)
通道类型的“未初始化”字段或变量的所有通道类型的零值为nil。因此,让我们研究一下nil通道或通道上的操作。
nil
值得 在一篇文章中收集 渠道公理 :
nil通道阻塞的原因:如果一个通道值为nil,则没有人引用它,因此没有人会准备好从中接收(我们要发送的内容);或发送任何内容(我们会从中收到什么)。
您可以在Dave Cheney:Channel Axioms中阅读更多的推理和更多详细信息。
为了完整性:
0
理由:“关闭”是一种状态,但是一个nil通道不能具有状态(只有一个nil通道,“关闭”通道没有一个通道,“非关闭”通道没有一个通道)。而且没有元素在nil通道中排队(因此len = 0),并且它没有缓冲区容量(因此cap = 0)。