Обычно сначала печатаются 0–4 с секундными промежутками, после закрытия канала — бесконечные нули. break внутри select не завершает внешний for.
Получение данных из канала с задержкой и ограничением по времени
Обычно сначала печатаются 0–4 с секундными промежутками, после закрытия канала — бесконечные нули. break внутри select не завершает внешний for.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Определите, какие сообщения появятся в выводе программы, учитывая работу канала, паузы между отправками и срабатывание тайм‑аута в конструкции select.
func main() {
ch := make(chan int)
go func() {
for i := 0; i < 5; i++ {
ch <- i
time.Sleep(time.Second)
}
close(ch)
}()
for {
select {
case v := <-ch:
fmt.Println(v)
case <-time.After(3 * time.Second):
fmt.Println("timeout")
break
}
}
}
Ответ
Обычно сначала печатаются 0–4 с секундными промежутками, после закрытия канала — бесконечные нули. break внутри select не завершает внешний for.
Чтение закрытого пустого канала сразу возвращает 0, поэтому ветка остаётся постоянно готовой. Нужно читать v, ok := <-ch и возвращаться при !ok.
time.After создаётся заново при каждой итерации, то есть это таймаут ожидания очередного значения, не общий трёхсекундный лимит программы. При срабатывании печатается timeout, но break выходит только из select. Для завершения используйте return или помеченный break; для общего дедлайна вынесите таймер за цикл. Точный вывод зависит и от задержек планировщика.