为什么从未达到 return 语句
Why never reached the return statement
看下面的代码片段
package main
import (
"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,通道关闭
for 循环的每次迭代都会创建一个新的两秒计时器。关闭的通道随时准备接收。代码永远循环,因为在关闭的通道准备好接收之前,新计时器的通道永远不会准备好接收。
解决此问题的一种方法是将频道设置为零:
case value, ok := <-ch:
if !ok {
ch = nil
} else {
fmt.Println(value)
}
在 nil 频道上接收永远不会准备好。
如果您希望循环 运行 最多两秒,那么您应该在循环外创建计时器:
after := time.After(time.Second * 2)
和select在循环中的这个计时器上:
case <-after:
fmt.Println("Return")
return
playground example(添加睡眠以在操场上做出示例运行)
您可以结合将通道设置为 nil 和在循环外创建计时器。
看下面的代码片段
package main
import (
"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,通道关闭
for 循环的每次迭代都会创建一个新的两秒计时器。关闭的通道随时准备接收。代码永远循环,因为在关闭的通道准备好接收之前,新计时器的通道永远不会准备好接收。
解决此问题的一种方法是将频道设置为零:
case value, ok := <-ch:
if !ok {
ch = nil
} else {
fmt.Println(value)
}
在 nil 频道上接收永远不会准备好。
如果您希望循环 运行 最多两秒,那么您应该在循环外创建计时器:
after := time.After(time.Second * 2)
和select在循环中的这个计时器上:
case <-after:
fmt.Println("Return")
return
playground example(添加睡眠以在操场上做出示例运行)
您可以结合将通道设置为 nil 和在循环外创建计时器。