English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
В языке Go заявление select подобноЗаявление switchНо в заявлении select случаи указывают на коммуникацию, то есть отправку или прием на канале.
Грамматика:
select{ case SendOrReceive1: // заявление case SendOrReceive2: // заявление case SendOrReceive3: // заявление ...... default: // заявление
Важные моменты:
Заявление select ждет готовности коммуникации (отправка или прием) для начала в некоторых случаях.
package main import ( "fmt" "time" ) // функция 1 func portal1(channel1 chan string) { time.Sleep(3 * time.Second) channel1 <- "Добро пожаловать на канал 1" } // функция 2 func portal2(channel2 chan string) { time.Sleep(9 * time.Second) channel2 <- "Добро пожаловать на канал 2" } func main() { // создание канала R1 := make(chan string) R2 := make(chan string) // вызов функций 1 и 2 с помощью goroutine go portal1(R1) go portal2(R2) select { // case 1 case op1 := <-R1: fmt.Println(op1) // case 2 case op2 := <-R2: fmt.Println(op2) } }
Вывод:
Добро пожаловать в канал 1
Объяснение использования:В предыдущем примере portal1 спит 3 секунды, portal2 спит 9 секунд, после окончания их времени сна они будут готовы продолжить. В настоящее время, заявление select ждет их время сна, когда portal2 проснется, он выберет case 2 и выведет "Добро пожаловать в канал 1". Если портал 1 проснется раньше, чем portal2, то выведется "Добро пожаловать в канал 2".
Если语句 select не содержит ни одного случая case, то это заявление select будет ждать вечно.
Грамматика:
select{}
package main func main() { // не содержит ни одного case, будет ждать постоянно select{ } }
Вывод:
фатальная ошибка: все goroutine спят - блокировка! goroutine 1 [select (no cases)]: main.main() /home/runner/main.go:9 +0x20 exit status 2
default в предложении select используется для защиты select от блокировки. Когда ни один из case не готов, выполняется это предложение.
package main import "fmt" func main() { // создание каналов mychannel := make(chan int) select { case <- mychannel: default: fmt.Println("Не найдено") } }
Вывод:
Не найдено
Блокировка select означает, что когда ни один из case не готов и select не содержит default, select будет блокироваться, пока не будет至少 одного case или сообщения, чтобы продолжить.
package main func main() { // создание каналов mychannel := make(chan int) // канал еще не готов // и безdefault select { case <- mychannel: } }
Вывод:
фатальная ошибка: все goroutine спят - блокировка! goroutine 1 [chan receive]: main.main() /home/runner/main.go:14 +0x52 exit status 2
В предложении select, если необходимо обработать несколько ситуаций, можно случайным образом выбрать одну из них.
package main import "fmt" // функция 1 func portal1(channel1 chan string){ for i := 0; i <= 3; i++{ channel1 <- "Добро пожаловать на канал 1" } } // функция 2 func portal2(channel2 chan string){ channel2 <- "Добро пожаловать на канал 2" } func main() { // создание каналов R1 := make(chan string) R2 := make(chan string) // использование goroutine для вызова функций 1 и 2 go portal1(R1) go portal2(R2) // случайный выбор одного из них select{ case op1 := <- R1: fmt.Println(op1) case op2 := <- R2: fmt.Println(op2) } }
Вывод:
Добро пожаловать на канал 2