Ответ
Оператор select
ведет себя по-разному в зависимости от состояния каналов.
- Если готов только один
case
: Выполняется именно он. -
Если готовы несколько
case
: Выбор одного из них происходит псевдослучайно. Это сделано для обеспечения справедливости (fairness) и предотвращения "голодания" (starvation), когда один и тот жеcase
выбирался бы всегда, блокируя остальные.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
не готов:select
блокирует выполнение горутины до тех пор, пока один изcase
не станет готов. -
Если есть ветка
default
: Если ни одинcase
не готов в момент проверки, выполняется веткаdefault
. Это делаетselect
неблокирующим.ch := make(chan int) select { case v := <-ch: fmt.Println("Получено:", v) default: fmt.Println("Никто не готов, выполняем default") }