Выбор ответа 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 и мусорные нули).
Варианты ответа
- Чтобы GC сразу освободил память закрытого канала и его буфер
- Чтобы при повторном close канал не вызвал панику
- Иначе компилятор не примет повторное чтение с ok из закрытого канала
- Закрытый канал всегда готов и крутил бы цикл, nil не готов никогдаправильный ответ
Разбор
Закрытый канал всегда готов к чтению и мгновенно отдаёт нулевое значение, поэтому select будет снова и снова выбирать эту ветку, пока второй канал ещё работает (busy loop и мусорные нули). Присвоив переменной nil, мы выключаем ветку, а цикл завершаем, когда оба стали nil. Память канала освобождает GC, повторное закрытие nil паникует, компилятор ничего такого не требует.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.