Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. Go Dictionary
  3. select

select

The select statement is a syntax for waiting on multiple channels simultaneously in Go's concurrent programming. It looks similar to a switch statement, but each case represents a channel send or receive operation. When multiple cases are ready, one is chosen at random.

Syntax

// Use select to wait on multiple channels at once.
select {
case v := <-ch1:
    // Runs when data is received from ch1.
case ch2 <- value:
    // Runs when data is successfully sent to ch2.
case v, ok := <-ch3:
    // Receives from ch3 and checks whether the channel is closed.
    if !ok {
        // ch3 has been closed.
    }
default:
    // Runs when no channel is ready (non-blocking).
}

Characteristics of select

CharacteristicDescription
Random selectionWhen multiple cases are ready at the same time, Go randomly picks one to execute.
BlockingWithout a default case, select blocks until at least one case becomes ready.
Non-blockingAdding a default case makes select return immediately if no channel is ready.
Timeout handlingCombine select with a time.After channel to implement timeout logic.

Sample Code

package main

import (
    "fmt"
    "time"
)

func main() {
    ch1 := make(chan string)
    ch2 := make(chan string)

    // Send data to each channel from separate goroutines.
    go func() {
        time.Sleep(100 * time.Millisecond)
        ch1 <- "message from ch1"
    }()
    go func() {
        time.Sleep(200 * time.Millisecond)
        ch2 <- "message from ch2"
    }()

    // Use select to wait for receives from both channels.
    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-ch1:
            fmt.Println("Received:", msg1)
        case msg2 := <-ch2:
            fmt.Println("Received:", msg2)
        }
    }

    fmt.Println()

    // Example of implementing a timeout.
    ch := make(chan int)
    go func() {
        time.Sleep(500 * time.Millisecond)
        ch <- 42
    }()

    select {
    case v := <-ch:
        fmt.Println("Received:", v)
    case <-time.After(300 * time.Millisecond):
        fmt.Println("Timed out")
    }

    // Example of a non-blocking receive.
    ch3 := make(chan int, 1)
    select {
    case v := <-ch3:
        fmt.Println("Received:", v)
    default:
        fmt.Println("No data in ch3 (non-blocking)")
    }
}

Overview

select is one of the core constructs in Go's concurrent programming model. It lets you efficiently multiplex multiple channels and write timeout logic concisely. The pattern of using select with a done channel is also the standard way to send a stop signal to a goroutine.

If select has no default case and none of its cases are ready, it will block forever and may cause a deadlock. Always design your select statements so they can exit — use a timeout or a default case.

For the basics of channels, see channel. For waiting on goroutines to finish, see sync.WaitGroup.

If you find any errors or copyright issues, please .