Оператор select
Оператор select позволяет горутине ожидать выполнения операций
приема или отправки данных через каналы. Он выбирает первый канал,
который готов к выполнению, и выполняет соответствующий блок кода.
Если несколько каналов готовы одновременно, выбор происходит случайным
образом. В первом параметре оператора мы передаем список операций
с каналами для ожидания.
Синтаксис
select {
case <-chan1:
// code
case chan2 <- value:
// code
default:
// code
}
Пример
Давайте создадим два канала и отправим данные в один из них,
затем используем select для получения данных из первого
готового канала:
package main
import "fmt"
func main() {
chan1 := make(chan string)
chan2 := make(chan string)
go func() {
chan1 <- "first"
}()
go func() {
chan2 <- "second"
}()
select {
case res1 := <-chan1:
fmt.Println(res1)
case res2 := <-chan2:
fmt.Println(res2)
}
}
Результат выполнения кода:
"first"
В зависимости от того, какая горутина первой отправит данные, результат может быть как "first", так и "second".
Пример
Рассмотрим использование select с блоком default,
который выполняется, если ни один из каналов не готов к операции:
package main
import "fmt"
func main() {
chan1 := make(chan int)
select {
case res := <-chan1:
fmt.Println(res)
default:
fmt.Println("No data received")
}
}
Результат выполнения кода:
"No data received"
Поскольку канал не содержит данных, выполняется блок
default, и программа выводит соответствующее сообщение.
Пример
Используем select для отправки данных в канал,
который готов принять значение:
package main
import "fmt"
func main() {
chan1 := make(chan string, 1)
select {
case chan1 <- "data":
fmt.Println("Data sent successfully")
default:
fmt.Println("Channel is full")
}
fmt.Println(<-chan1)
}
Результат выполнения кода:
"Data sent successfully"
"data"
Благодаря буферизированному каналу с емкостью 1 отправка данных выполняется успешно, после чего мы получаем отправленное значение.
Смотрите также
-
оператор
select-default,
который используется для неблокирующих операций с каналами -
конструкцию
go,
которая запускает горутины для асинхронного выполнения функций -
каналы
chan,
которые используются для обмена данными между горутинами -
буферизированные каналы
buffered-chan,
которые позволяют хранить несколько значений без получателя