Каналы: буферизованные и небуферизованные, закрытие, чтение из закрытого
Канал — типизированная очередь и одновременно средство синхронизации. Небуферизованный канал синхронен: отправка блокируется, пока другая горутина не начнёт приём, поэтому он не столько передаёт данные, сколько устанавливает момент встречи. Буферизованный принимает до ёмкости без блокировки и блокирует отправителя только на заполненном буфере. Правила закрытия жёсткие и часто нарушаются: закрывает только отправитель, закрывать дважды или отправлять в закрытый канал — паника. Приём из закрытого канала, наоборот, безопасен: он немедленно возвращает нулевое значение, а форма v, ok := <-ch даёт ok == false; range по каналу завершается сам при закрытии. Отсюда идиома «закрытие как широковещательный сигнал»: канал done chan struct{} закрывают, и все ожидающие разблокируются разом. Отдельно стоит nil-канал: и приём, и отправка блокируются навсегда — свойство, которое осмысленно используют в select.