Ответ
Объявление канала через var ch chan int
без его инициализации с помощью make()
создает нулевой (nil
) канал. Работа с таким каналом имеет свои особенности, которые часто приводят к проблемам.
Проблемы с нулевым (nil
) каналом:
-
Бесконечная блокировка (deadlock): Любая операция отправки или получения данных из
nil
-канала блокирует горутину навечно. Это одна из самых частых причинdeadlock
у новичков.var ch chan int // ch == nil <-ch // Горутина заблокируется здесь навсегда ch <- 1 // И здесь тоже
-
Паника при закрытии: Попытка закрыть
nil
-канал с помощьюclose(ch)
немедленно вызывает панику.var ch chan int // ch == nil close(ch) // panic: close of nil channel
Правильное создание канала
Всегда инициализируйте канал с помощью встроенной функции make()
перед использованием:
// Небуферизованный канал
ch1 := make(chan int)
// Буферизованный канал на 10 элементов
ch2 := make(chan int, 10)
Когда nil
-канал может быть полезен?
Несмотря на проблемы, nil
-каналы иногда используются намеренно. Например, в цикле for
с несколькими операторами select
, можно присвоить каналу nil
, чтобы временно "отключить" соответствующий case
, не меняя структуру цикла.