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

Why does select in golang only works with channels in goroutine?

考虑以下 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

Shouldn't the code execute in a sequential manner in the first case so that by the time the select statement is reached, the msg will be passed and it will catch the case msg := <-messages ?

从未达到 select 语句,这是您第一个代码中的问题。

声明

messages <- "my msg"

想要将字符串推送到通道中,但由于您创建了一个无缓冲通道

messages := make(chan string)

goroutine 一直在等待有人真正从通道读取数据,因此它可以将字符串推送到通道。你可以将一些东西推送到一个无缓冲的通道如果有一个goroutine从它读取的地方!

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

messages := make(chan string, 1)

它应该会如您所愿。