看下面的代码片段package mainimport ( "fmt" "time")func sender(ch chan string) { ch <- "Hello" ch <- "Foo" ch <- "and" ch <- "Boo" close(ch)}func main() { ch := make(chan string) go sender(ch) for { select { case value := <-ch: fmt.Println(value) case <-time.After(time.Second * 2): fmt.Println("Return") return } }}结果我得到了空白输出和 time.After 将永远不会到达。为什么?我注意到,当我尝试从关闭的通道接收值时,它将从类型接收零值。为什么我仍然可以从关闭的渠道获得价值?我也可以检查也喜欢,v, ok := <-ch如果 ok 为 false,则通道关闭。
1 回答
明月笑刀无情
TA贡献1828条经验 获得超4个赞
在 for 循环的每次迭代中都会创建一个新的两秒计时器。关闭的频道随时准备接收。代码永远循环,因为在关闭的通道准备好接收之前,新定时器的通道永远不会准备好接收。
解决问题的一种方法是将通道设置为 nil:
case value, ok := <-ch:
if !ok {
ch = nil
} else {
fmt.Println(value)
}
在 nil 频道上接收永远不会准备好。
如果您希望循环最多运行两秒钟,那么您应该在循环外创建计时器:
after := time.After(time.Second * 2)
并在循环中选择这个计时器:
case <-after:
fmt.Println("Return")
return
操场示例(添加睡眠以使示例在操场上运行)
您可以将通道设置为 nil 并在循环外创建计时器。
- 1 回答
- 0 关注
- 156 浏览
添加回答
举报
0/150
提交
取消