Получение данных из канала с задержкой и ограничением по времени

Обычно сначала печатаются 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; для общего дедлайна вынесите таймер за цикл. Точный вывод зависит и от задержек планировщика.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее