给出以下简单的Go程序:
ch := make(chan int)
go fmt.Println(<- ch)
ch <- 2
如果我将go fmt.Println(<- ch)
替换为go func(){fmt.Println(<-ch)}()
,则效果很好。
但是使用原始版本,我得到了:
fatal error: all goroutines are asleep - deadlock!
为什么?
答案 0 :(得分:3)
根据spec的定义:
函数值和参数在调用goroutine中照常进行评估,但是与常规调用不同,程序执行不等待调用的函数完成。相反,该函数开始在新的goroutine中独立执行。当函数终止时,其goroutine也终止。如果该函数具有任何返回值,则在函数完成时将其丢弃。
因此<-ch
被求值。但是它不能,因为通道是空的,因此它一直阻塞直到有东西写入它。但是从来没有写过任何东西,因此这是一个僵局。
将其包装在匿名函数中时-发生相同的情况,但对于匿名函数。然后,将其主体与主goroutine同时评估。