Материал проходит вычитку — возможны неточности.
Урок 80 из 118

range, направленные, nil-канал

Аня попросила сделать видимым, кто в конвейере писал, а кто читал: глядя на сигнатуру шага, было ясно, куда тёк поток файлов. Миша переписал шаги — сигнатуры указали направление, а циклы чтения сократились до простого range.

Главная мысль

range по каналу читает до закрытия; направленные типы (chan<-, <-chan) ограничивают, кто что может делать; nil-канал блокирует обе операции навсегда.

Range до закрытия

for f := range ch {
    process(f)
}
// цикл вышел — канал закрыт и опустошён

range по каналу читает значения, пока канал не закроется и не опустеет. Это идиоматичная замена ручному циклу с ok из прошлого урока — короче и без ошибки «забыл проверить ok».

Направленные типы

func produce(out chan<- File) { // шаг может только отправлять
    out <- file
    close(out)
}

func consume(in <-chan File) { // шаг может только принимать
    for f := range in {
        fmt.Println(f)
    }
}

ch := make(chan File)
go produce(ch)
consume(ch)

chan<- File — только отправка, <-chan File — только приём. Компилятор следит: попытка читать из chan<- или писать в <-chan — ошибка сборки. Обычный chan File приводится к обоим направлениям автоматически. Направленные типы документируют намерение в сигнатуре: глядя на produce(out chan<- File), сразу понятно, кто пишет, а кто читает — в конвейере это и есть договор между шагами.

Nil-канал блокирует навсегда

var ch chan int // nil
ch <- 1 // блокировка навсегда
<-ch    // блокировка навсегда

Кажется, что это источник вечных блокировок, но nil-канал — инструмент: в select его case можно «выключить», присвоив каналу nil. Подробнее — в уроке.

В следующем уроке

Вы узнаете:

  • почему close(chan<-) разрешён, а close(<-chan) нет
  • чем range отличается от ручного цикла с ok по производительности
<!-- wp:course-hub/quiz {"title":"Проверьте себя","questions":[{"text":"var ch chan int (nil). select { case v :=
Итоги

range — чтение до закрытия; направленные типы — контроль доступа на уровне компиляции; nil-канал — вечная блокировка, полезная в select.

Наш сайт собирает куки. Чтобы тебе было удобнее им пользоваться. Нажимая на кнопку, ты даёшь разрешение собирать куки