Go by Example

Select

Wait on multiple channel operations simultaneously - select proceeds with whichever case is ready first.

select lets a goroutine wait on multiple channel operations at once. It blocks until one case can proceed, then executes it. If multiple cases are ready simultaneously, one is chosen at random.

Two goroutines each send to their own channel after a short delay. select receives whichever message arrives first.

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"
    }()
 
    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-c1:
            fmt.Println("Received", msg1)
        case msg2 := <-c2:
            fmt.Println("Received", msg2)
        }
    }
}

A default case makes select non-blocking - if no channel is ready it falls through to default immediately:

select {
case msg := <-messages:
    fmt.Println("received message", msg)
case sig := <-signals:
    fmt.Println("received signal", sig)
default:
    fmt.Println("no activity")
}

A nil channel in a select case is permanently blocked - it is never selected. This lets you disable a case at runtime without restructuring the select:

var retry <-chan time.Time // nil - never fires
 
for {
    select {
    case result := <-work:
        fmt.Println("got result:", result)
        retry = nil // success: disable retry
    case <-retry:
        fmt.Println("retrying...")
    case <-time.After(5 * time.Second):
        retry = time.After(500 * time.Millisecond) // enable retry
    }
}

In production

A nil channel in a select case is permanently blocked - it is never selected. This is a useful pattern to disable a case at runtime without restructuring the select. Use it to "turn off" a retry branch once a success is received, or to drain a done channel before re-enabling a work channel. When multiple cases are ready simultaneously, select picks one at random - do not rely on ordering for correctness.

Enjoyed this? Get more essays on software craft delivered to your inbox.

Subscribe free