具有通道参数的函数中的死锁

Deadlock in function which has a channel parameter

给定以下简单的 Go 程序:

ch := make(chan int)
go fmt.Println(<- ch)
ch <- 2

如果我用 go func(){fmt.Println(<-ch)}() 替换 go fmt.Println(<- ch),效果很好。

但是我得到的原始版本是:

fatal error: all goroutines are asleep - deadlock!

为什么?

定义在spec:

The function value and parameters are evaluated as usual in the calling goroutine, but unlike with a regular call, program execution does not wait for the invoked function to complete. Instead, the function begins executing independently in a new goroutine. When the function terminates, its goroutine also terminates. If the function has any return values, they are discarded when the function completes.

所以 <-ch 被评估。但它不能,因为通道是空的,因此它会阻塞,直到有东西写入它。但是从来没有任何东西写入它,因此这是一个死锁。

当您将其包装在匿名函数中时 - 发生同样的情况,但对于匿名函数。然后它的主体被同时评估到主 goroutine。