为了账号安全,请及时绑定邮箱和手机立即绑定

为什么从来没有到达return语句

为什么从来没有到达return语句

Go
慕工程0101907 2021-09-10 21:21:48
看下面的代码片段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 并在循环外创建计时器。


查看完整回答
反对 回复 2021-09-10
  • 1 回答
  • 0 关注
  • 156 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信