为什么golang中的select只适用于goroutine中的channel?

时间:2016-09-06 00:04:07

标签: go channel

考虑以下go playground

    package main

    import "fmt"

    func main() {
        messages := make(chan string)

        messages <- "my msg"

        select {
        case msg := <-messages:
            fmt.Println("received message", msg)
        }

    }

上面的代码会出错

fatal error: all goroutines are asleep - deadlock!

然而

如果我将其更改为

    package main

    import "fmt"

    func main() {
        messages := make(chan string)

        go func() {
            messages <- "my msg"
        }()
        select {
        case msg := <-messages:
            fmt.Println("received message", msg)
        }

    }

它会起作用。

这种行为有特殊原因吗?

代码不应该在第一种情况下以顺序方式执行,以便在到达select语句时,msg将被传递并且它将捕获案例msg := <-messages

1 个答案:

答案 0 :(得分:6)

  

代码不应该在第一种情况下以顺序方式执行,以便在达到select语句时,msg将被传递并且它将捕获case msg:=&lt; -messages?

永远不会达到select语句,这就是第一个代码中的问题。

声明

messages <- "my msg"

想要将字符串推入频道,但是因为您创建了一个无缓冲的频道

messages := make(chan string)

goroutine一直在等待某人实际从频道中读取,因此它可以将字符串推送到频道。您可以将某些内容推送到无缓冲的频道如果某处有一个goroutine读取内容!

尝试使用缓冲通道的第一个示例:

messages := make(chan string, 1)

它应该按照您的预期工作。