Выбор ответа Senior Каналы и select обновлено

Выключение ветки select через nil

Вопрос

Зачем в слиянии двух каналов после закрытия a пишут a = nil?

for a != nil || b != nil {
    select {
    case v, ok := <-a:
        if !ok { a = nil; continue }
        out <- v
    case v, ok := <-b:
        if !ok { b = nil; continue }
        out <- v
    }
}

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Закрытый канал всегда готов и крутил бы цикл, nil не готов никогда. Закрытый канал всегда готов к чтению и мгновенно отдаёт нулевое значение, поэтому select будет снова и снова выбирать эту ветку, пока второй канал ещё работает (busy loop и мусорные нули).

Варианты ответа

  1. Чтобы GC сразу освободил память закрытого канала и его буфер
  2. Чтобы при повторном close канал не вызвал панику
  3. Иначе компилятор не примет повторное чтение с ok из закрытого канала
  4. Закрытый канал всегда готов и крутил бы цикл, nil не готов никогдаправильный ответ

Разбор

Закрытый канал всегда готов к чтению и мгновенно отдаёт нулевое значение, поэтому select будет снова и снова выбирать эту ветку, пока второй канал ещё работает (busy loop и мусорные нули). Присвоив переменной nil, мы выключаем ветку, а цикл завершаем, когда оба стали nil. Память канала освобождает GC, повторное закрытие nil паникует, компилятор ничего такого не требует.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.