Назовите основные правила (‘аксиомы’) работы с каналами в Go.

Ответ

Основные правила (или "аксиомы") при работе с каналами в Go, знание которых помогает избегать паник и дедлоков:

  1. Отправка в закрытый канал вызывает панику.

    • После close(ch) любая операция ch <- data приведет к panic: send on closed channel.
      ch := make(chan int)
      close(ch)
      ch <- 1 // panic: send on closed channel
  2. Чтение из закрытого канала никогда не блокируется.

    • Вместо блокировки операция чтения немедленно возвращает нулевое значение для типа данных канала. Вторая переменная в v, ok := <-ch будет false, что позволяет определить, был ли канал закрыт.
    • Это свойство обеспечивает корректное завершение циклов for range по каналу.
      ch := make(chan int, 1)
      ch <- 42
      close(ch)
      v, ok := <-ch // v = 42, ok = true
      v, ok = <-ch  // v = 0,  ok = false
  3. Закрытие уже закрытого канала вызывает панику.

    • close(ch) можно вызывать только один раз.
      ch := make(chan int)
      close(ch)
      close(ch) // panic: close of closed channel
  4. Отправка в nil-канал блокируется навсегда.

    var ch chan int // ch == nil
    ch <- 1         // deadlock
  5. Чтение из nil-канала блокируется навсегда.

    • Это свойство (вместе с предыдущим) является полезным идиоматическим приемом. В операторе select можно присвоить каналу nil, чтобы временно "отключить" соответствующий case.
      var ch chan int // ch == nil
      <-ch            // deadlock
  6. Закрытие nil-канала вызывает панику.

    var ch chan int // ch == nil
    close(ch)       // panic: close of nil channel