Ответ
В Go для проверки состояния канала используется вторая переменная, возвращаемая при операции чтения. Это идиоматичный и основной способ.
1. Проверка при чтении
При чтении из канала можно получить два значения: само значение и флаг ok
(boolean).
value, ok := <-ch
- Если
ok
равноtrue
, канал открыт иvalue
содержит успешно прочитанное значение. - Если
ok
равноfalse
, канал закрыт. При этомvalue
будет содержать нулевое значение для типа данных канала (например,0
дляint
,""
дляstring
,nil
для указателей).
ch := make(chan int, 1)
ch <- 10
close(ch)
v, ok := <-ch
fmt.Printf("Прочитано: %d, канал открыт: %vn", v, ok) // Прочитано: 10, канал открыт: true
v, ok = <-ch
fmt.Printf("Прочитано: %d, канал открыт: %vn", v, ok) // Прочитано: 0, канал открыт: false
2. Использование цикла for range
Цикл for v := range ch
автоматически прекращает работу, когда канал закрывается и все значения из него прочитаны. Это самый удобный способ читать все данные из канала до его закрытия.
for value := range ch {
// Этот код выполняется для каждого значения в канале
fmt.Println("Получено:", value)
}
// Цикл завершится, когда канал 'ch' будет закрыт и опустошен.
// Здесь мы знаем, что канал точно закрыт.
Важное замечание
- Запись в закрытый канал вызывает панику. Проверить канал на закрытие перед записью невозможно напрямую. Координировать закрытие канала должна та горутина, которая в него пишет (или используется специальный сигнальный канал).