Перейти к содержимому
3 / 15

Оператор select: множественное ожидание, default и таймауты

select ждёт сразу нескольких канальных операций и выполняет ту ветку, которая готова первой. Если готовы несколько — выбирается случайная, и это сделано намеренно, чтобы никто не полагался на приоритет веток. Если не готова ни одна, select блокируется; ветка default превращает его в неблокирующую попытку. Отсюда основные применения. Таймаут: case <-time.After(d) ограничивает ожидание; до Go 1.23 такой таймер не собирался сборщиком до срабатывания, и в циклах вместо него советовали time.NewTimer — сейчас это правило отменено, но Timer по-прежнему нужен там, где отсчёт надо перевзводить после каждого события, а не начинать заново. Отмена: case <-ctx.Done() — стандартный способ прервать ожидание. Неблокирующая отправка: default позволяет отбросить сообщение вместо блокировки. И приём, который отличает знающего: nil-канал в ветке блокируется навсегда, поэтому присваивание ch = nil — штатный способ выключить ветку в цикле, не переписывая select.