Тупик в функции, которая имеет параметр канала - PullRequest
3 голосов
/ 16 марта 2019

Учитывая следующую простую программу 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!

Почему?

1 Ответ

3 голосов
/ 16 марта 2019

Как определено в спецификации :

Значение функции и параметры оцениваются, как обычно, в вызывающей программе, но в отличие от обычного вызова, выполнение программы не ожидает завершения вызванной функции. Вместо этого функция начинает выполняться независимо в новой процедуре. Когда функция завершается, ее процедура также завершается. Если функция имеет какие-либо возвращаемые значения, они отбрасываются после завершения функции.

Таким образом, <-ch оценивается. Но это невозможно, поскольку канал пуст, следовательно, он блокируется, пока что-то не пишет в него. Но в него никогда ничего не пишется, следовательно, это тупик.

Когда вы заключаете его в анонимную функцию - происходит то же самое, но для анонимной функции. И затем его тело оценивается одновременно с главной программой.

...