Go за Прикладом: Select

Go’шний select (вибір) дозволяє вам очікувати операцій з кількома каналами. Комбінування горутин та каналів з select це надзвичайно корисна особливість Go.

package main
import (
    "fmt"
    "time"
)

Наприклад - ми хочемо обирати поміж двох каналів.

func main() {
    c1 := make(chan string)
    c2 := make(chan string)

Кожен канал отримає значення після якогось проміжку часу, так ми симулюємо, скажімо, блокуючі виклики від сторонніх сервісів, що виконуються одночасних горутинах.

    go func() {
        time.Sleep(1 * time.Second)
        c1 <- "one"
    }()
    go func() {
        time.Sleep(2 * time.Second)
        c2 <- "two"
    }()

Ми застосуємо select для очікування обох значень одночасно, передавши повідомлення на екран - відразу по-отриманні.

    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-c1:
            fmt.Println("received", msg1)
        case msg2 := <-c2:
            fmt.Println("received", msg2)
        }
    }
}

Ми отримаємо спочатку значення один, а вже потім два - так як і задумувалось.

$ time go run select.go
received one
received two

Зауважте, що час виконання близько 2 секунд - оскільки і для 1-шої, і для 2-гої секунди команда Sleep (спати) виконується одночасно.

real    0m2.245s

Наступний приклад: Тайм-аути (Timeouts).