Получить доступ

Как работает select в Go?

JuniorГорутины и каналы
Ещё спрашивают так:
  • Как сделать таймаут при чтении из канала?
Коротко

select ждёт сразу несколько операций с каналами и выполняет ту, что готова первой; если готовы несколько — случайную. Ветка default делает select неблокирующим. Таймаут — ветка <-time.After(d) или <-ctx.Done().

  • Пустой select{} блокирует навсегда
  • nil-канал в select никогда не готов — так «выключают» ветку
  • Случайный выбор предотвращает голодание одного канала

А ещё time.After в цикле создаёт таймер на каждой итерации — лучше time.NewTimer или context

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Типичные шаблоны:

  • таймаут — ветка с таймером или контекстом;
  • отмена — <-ctx.Done() в каждом цикле обработки;
  • неблокирующая попытка — default;
  • слияние нескольких источников — несколько case на получение;
  • отключение ветки — присвоить каналу nil, когда он закрыт.

Select выбирает среди готовых случайно — нельзя полагаться на порядок веток как на приоритет. Приоритет делают вложенными select.

Пример

select {
case msg := <-messages:
    handle(msg)
case <-ctx.Done():
    return ctx.Err()
case <-time.After(2 * time.Second):
    return errors.New("таймаут")
}

select {                 // неблокирующая отправка
case events <- e:
default:
    dropped++
}

Что хотят услышать

  • Выбор готовой операции, случайность.
  • default и таймауты.

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем