Ответ
Да, в Go каналы могут быть однонаправленными. Это означает, что канал можно использовать только для отправки или только для получения данных. Это ограничение обеспечивается на уровне системы типов компилятором.
- Канал только для отправки:
chan<- T
- Канал только для получения:
<-chan T
Основное преимущество — повышение безопасности и выразительности кода. Когда функция принимает однонаправленный канал в качестве аргумента, её сигнатура четко говорит о том, как она будет этот канал использовать. Это предотвращает случайные ошибки, например, отправку данных в канал, который предназначен только для чтения.
Пример:
// Эта функция может только отправлять данные в канал
func sender(ch chan<- int) {
ch <- 42
// <-ch // Ошибка компиляции: invalid operation: cannot receive from send-only channel
}
// Эта функция может только получать данные из канала
func receiver(ch <-chan int) {
fmt.Println(<-ch)
// ch <- 100 // Ошибка компиляции: invalid operation: cannot send to receive-only channel
}
func main() {
// Создаем обычный двунаправленный канал
ch := make(chan int)
// Передаем его в горутины, которые работают с ним как с однонаправленным
go sender(ch)
receiver(ch)
}
Таким образом, однонаправленные каналы — это мощный инструмент для проектирования безопасных и понятных конкурентных API.