Можно ограничить канал на только отправку или только получение — через типизацию:
func producer(out chan<- int) { // только отправка
out <- 42
// <-out // ошибка компиляции!
}
func consumer(in <-chan int) { // только получение
val := <-in
// in <- 1 // ошибка компиляции!
fmt.Println(val)
}
func main() {
ch := make(chan int) // двунаправленный
go producer(ch) // неявно конвертируется в chan<-
consumer(ch) // неявно конвертируется в <-chan
}
Зачем:
- Документирует намерение: читаешь сигнатуру — понимаешь роль
- Компилятор не даст случайно отправить в read-only канал
- Двунаправленный канал неявно конвертируется в однонаправленный, но не наоборот