Skip to main content

Command Palette

Search for a command to run...

Golang Concurrency #5 - Select

Published
1 min read
Golang Concurrency #5 - Select
T

Just a guy who loves to write code and watch anime.

Select statement

Select lets you wait on multiple channel operations at once. It picks whichever channel is ready first.

Basic syntax

select {
case value := <-ch1:
    // Handle ch1
case value := <-ch2:
    // Handle ch2
}

Key clarifications

1. Select runs exactly once

2. If multiple cases are ready, select picks randomly (not chronological order).

3. Select with sending

select {
case ch1 <- "hello":  // Try to send
    fmt.Println("Sent to ch1")
case msg := <-ch2:    // Try to receive
    fmt.Println("Got from ch2")
}

Select tries both operations. Whichever can happen first, happens. Sending only works if there's buffer space or a receiver waiting.

4. Default case (non-blocking)

select {
case msg := <-ch:
    fmt.Println("Got message")
default:
    fmt.Println("No message ready")  // Runs immediately if ch not ready
}

Without default, select blocks until a channel is ready. With default, it never blocks.

5. Why receivers usually need goroutines

ch := make(chan int)
ch <- 42        // BLOCKS forever - no receiver ready
value := <-ch   // Never executes

With unbuffered channels, sender and receiver must be in different goroutines because they need to "meet" simultaneously.

Common timeout pattern

select {
case result := <-ch:
    fmt.Println("Got result")
case <-time.After(5 * time.Second):
    fmt.Println("Timeout!")
}