Ответ
В операторе select
нет предопределенного приоритета. Выбор case
для выполнения подчиняется следующим правилам:
-
Если готовы несколько
case
(т.е. коммуникация по нескольким каналам возможна),select
выбирает один из них псевдослучайным образом. Это сделано для предотвращения "голодания" (starvation) одного из каналов, когда другой всегда готов.ch1 := make(chan int, 1) ch2 := make(chan int, 1) ch1 <- 1 ch2 <- 2 // Оба канала готовы к чтению select { case v := <-ch1: fmt.Println("Получено из ch1:", v) case v := <-ch2: fmt.Println("Получено из ch2:", v) } // При каждом запуске результат может быть разным
-
Если ни один
case
не готов, поведение зависит от наличия веткиdefault
:- Если есть
default
, выполняется он, иselect
не блокируется. - Если
default
отсутствует,select
блокирует текущую горутину до тех пор, пока один изcase
не станет готов к выполнению.
- Если есть
-
Если
select
не содержит ни одногоcase
(например,select {}
), он блокируется навсегда. Это может быть полезно для блокировки основной горутины в конце программы, чтобы другие горутины успели завершить работу.