Le Go par l'exemple: Select

Le select de go permet d’attendre plusieurs opérations sur les canaux. Combiner les goroutines et les canaux est une fonctionnalité puissante de Go.

package main
import "time"
import "fmt"

Pour notre exemple, nous ferons des select à travers deux canaux.

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

Chaque canal va recevoir une valeur après un certain temps, pour simuler une opération bloquante (par ex. un appel RPC) qui s’exécute dans une goroutine concurrente.

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

Nous utilisons select pour attendre ces deux valeurs simultanément, en affichant chacune d’elle dès qu’elle arrive.

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

Nous recevons les valeurs "one" puis "two" comme attendu.

$ time go run select.go 
received one
received two

A noter que le temps total d’exécution est seulement de ~2 secondes, car les deux Sleeps s’exécutent de manière concurrente.

real	0m2.245s

Exemple suivant: Timeouts.