猿问

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

看下面的代码片段


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,则通道关闭。


慕工程0101907
浏览 157回答 1
1回答

明月笑刀无情

在 for 循环的每次迭代中都会创建一个新的两秒计时器。关闭的频道随时准备接收。代码永远循环,因为在关闭的通道准备好接收之前,新定时器的通道永远不会准备好接收。解决问题的一种方法是将通道设置为 nil:&nbsp; &nbsp; case value, ok := <-ch:&nbsp; &nbsp; &nbsp; &nbsp; if !ok {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ch = nil&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(value)&nbsp; &nbsp; &nbsp; &nbsp; }在 nil 频道上接收永远不会准备好。如果您希望循环最多运行两秒钟,那么您应该在循环外创建计时器:&nbsp; &nbsp; after := time.After(time.Second * 2)并在循环中选择这个计时器:&nbsp; &nbsp; case <-after:&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Return")&nbsp; &nbsp; &nbsp; &nbsp; return操场示例(添加睡眠以使示例在操场上运行)您可以将通道设置为 nil 并在循环外创建计时器。
随时随地看视频慕课网APP

相关分类

Go
我要回答