问题描述
我有一个结构体,其中包含一个未初始化的通道.
I have a struct that holds a channel that is not initialized.
当我写入它时,例程按预期阻塞,但从未通知读者管道中有东西.
When I write into it, the routine is blocking as expected but the reader is never notified that something is in the pipe.
我很惊讶没有错误,我想知道 Go 在做什么.
I am surprised that there is no error and I am wondering what is doing Go.
在下面的示例中,消息 pushed
和 got it
都没有打印出来.(取消注释初始化,它会像魅力一样工作)
In the example bellow, neither the message pushed
nor got it
are printed. (Uncomment the intialization and it will work like a charm)
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 中发生了什么.)
(I know I should initialize the channel, this is not the purpose of the question, I want to know what is happening in Go with non initialized channels.)
推荐答案
的未初始化"字段或变量频道类型将具有所有频道类型的零值,即nil代码>.因此,让我们检查
nil
通道或对它的操作的行为.
An "uninitialized" field or variable of channel type will have the zero value of all channel types which is nil
. So let's examine how a nil
channel or operations on it behave.
值得在一篇文章中收集频道公理:
- a send on a
nil
channel blocks forever (Spec: Send statements) - a receive from a
nil
channel blocks forever (Spec: Receive operator) - a send to a closed channel panics (Spec: Send statements)
- a receive from a closed channel returns the zero value immediately (Spec: Receive operator)
在 nil
通道的情况下阻塞的原因:如果通道值为 nil
,则没有人引用它,因此没有人准备好接收从它(我们想要发送的);或者在上面发送任何东西(我们会从中收到什么).
Reasoning for blocking in case of nil
channels: if a channel value is nil
, no one has a reference to it, so no one will ever be ready to receive from it (what we want to send); or send anything on it (what we would receive from it).
您可以在 Dave Cheney:Channel Axioms 中阅读有关此的进一步推理和更多详细信息.
为了完整性:
- Closing a
nil
channel causes a run-time panic (just like closing an already closed channel). - Length and capacity of a
nil
channel is0
; in accordance withnil
slices and maps having0
length and capacity.
推理:关闭"是一种状态,但nil
通道不能有状态(只有一个nil
通道,而关闭"和一个用于未关闭"通道).并且在 nil
通道中没有元素排队(所以 len = 0),并且它没有缓冲容量(所以 cap = 0).
Reasoning: "closed" is a state, but a nil
channel cannot have a state (there is only one nil
channel, and not one for "closed" and one for "not closed" channel). And there are no elements queued in a nil
channel (so len = 0), and it does not have a buffer capacity (so cap = 0).
这篇关于未初始化的通道如何表现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!