select — как switch, но для каналов. Ждёт, пока одна из операций с каналом станет доступна. Если несколько готовы одновременно — выбирается случайная.
select {
case msg := <-ch1:
handle(msg)
case ch2 <- data:
// отправлено
case <-ctx.Done():
return ctx.Err()
case <-time.After(5 * time.Second):
return errors.New("timeout")
default:
// ничего не готово, не блокируемся
}
default делает select неблокирующим. Типичные паттерны: таймауты, отмена через context, мультиплексирование каналов, fan-in.