Что такое однонаправленные каналы в Go и для чего они используются?

Ответ

Да, в 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.