Вопрос проверяет понимание жизненного цикла каналов и безопасных паттернов их использования.
Прямого способа проверить, закрыт ли канал, не существует. Обычно закрытие определяют при чтении из канала через форму value, ok := <-ch. Если ok == false, канал закрыт. Безопасная работа с каналами включает правильное закрытие, использование range и контроль владельца канала.
В Go нет встроенной функции вроде isClosed(ch), потому что состояние канала может измениться сразу после проверки, что сделало бы такую функцию бесполезной.
Самый распространенный способ — чтение с проверкой второго значения.
v, ok := <-ch
if !ok {
// канал закрыт
}
Механика:
Если канал закрыт и пуст, ok будет false.
Если канал закрыт, но в нем есть данные — они сначала будут прочитаны.
Это безопасный и идиоматичный способ чтения:
for v := range ch {
// обработка
}
Цикл завершится автоматически после закрытия канала.
Обычно применяются следующие правила:
Канал закрывает только отправитель.
Не закрывать канал из нескольких goroutine.
Не отправлять данные в закрытый канал.
Select позволяет избежать блокировок:
select {
case v := <-ch:
_ = v
default:
// канал пуст
}
Закрытие канала определяется при чтении, а безопасная работа достигается через строгие правила владения каналом и идиоматичные конструкции вроде range.