Go by Example: Select

El select de Go te permite esperar en múltiples operaciones de canal. Combinar goroutines y canales con select es una característica poderosa de Go.

package main
import (
    "fmt"
    "time"
)
func main() {

Para nuestro ejemplo, seleccionaremos entre dos canales.

    c1 := make(chan string)
    c2 := make(chan string)

Cada canal recibirá un valor después de cierta cantidad de tiempo, para simular, por ejemplo, operaciones de RPC bloqueantes que se ejecutan en goroutines concurrentes.

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

Usaremos select para esperar ambos valores simultáneamente, imprimiendo cada uno a medida que llega.

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

Recibimos los valores "uno" y luego "dos" como se esperaba.

$ time go run select.go 
received one
received two

Nota que el tiempo total de ejecución es solo de ~2 segundos ya que ambos Sleeps de 1 y 2 segundos se ejecutan concurrentemente.

real    0m2.245s

Siguiente ejemplo: Timeouts.