当我运行以下简单代码时,它会按预期打印“ping”:
messages := make(chan string)
go func() { messages <- "ping" }()
fmt.Println(<-messages)
Run Code Online (Sandbox Code Playgroud)
但是,当我在 select 中使用相同的非缓冲通道时,它不会通过 ping 来实现它,从而打印“未发送消息”:
messages := make(chan string)
select {
case messages <- "ping":
fmt.Println("sent message")
default:
fmt.Println("no message sent")
}
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况?通道是相同的,但可以通过 goroutine 访问,但不能通过 select 访问。
此外,我发现当我将其转换为缓冲通道(大小为 1)时,它会像魅力一样满足通道的要求:为什么?
messages := make(chan string,1)
select {
case messages <- "ping":
fmt.Println("sent message")
default:
fmt.Println("no message sent")
}
Run Code Online (Sandbox Code Playgroud)
请注意,没有任何挂起,但正如我所描述的那样,立即返回。
该select语句将阻塞,直到其中任何一个case准备好为止,或者default如果没有一个准备好,则运行该案例。
在你的第二个程序中,之前没有出现接收操作select,因此case messages <- "ping"未准备好\xe2\x80\x94,没有接收器\xe2\x80\x94,并且default始终执行。
使用缓冲通道,即使另一端没有接收器,发送操作也不会阻塞,因此case messages <- "ping"已准备好并运行。
在带有 goroutine 的代码片段中,发送操作并发运行,因此主程序流程可以继续进行调用fmt.Println并阻塞<-messages,直到并发发送在通道上提供可用的值
| 归档时间: |
|
| 查看次数: |
3033 次 |
| 最近记录: |