SoFunction
Updated on 2025-05-14

Detailed explanation of the use of select in Go language

What is select?

selectYes used in GoMulti-channel operationThe control structure of  , which can listen to the sending and receiving operations of multiple channels,Execute the corresponding statement when one of them can be performed, thereby realizing non-blocking concurrent communication.

Basic syntax

select {
case val := <-ch1:
    // Execute when ch1 is readablecase ch2 <- 100:
    // ch2 is executed when it is writabledefault:
    // Execute when all channels are blocked (optional)}
  • EachcaseMust beSend (ch <- val) or receive (val := <-ch)

  • Only one actionablecase(If there are multiple ones, you can choose one at random)

  • If all block, and nodefaultselectWill block and wait

  • If includeddefault, it will execute immediately, even if it is othercaseIt is possible to operate afterwards

Examples of usage scenarios

1. Listen to data from multiple channels

select {
case msg1 := &lt;-ch1:
    ("Received ch1:", msg1)
case msg2 := &lt;-ch2:
    ("Received ch2:", msg2)
}

2. Implement the timeout mechanism

select {
case msg := &lt;-ch:
    ("receive:", msg)
case &lt;-(2 * ):
    ("time out")
}

Returns a channel that becomes readable after a specified time, achieving elegant timeout.

3. Non-blocking sending or receiving (default branch)

select {
case ch &lt;- data:
    ("Send successfully")
default:
    ("channel full, give up sending")
}

4. Check whether the channel is closed

select {
case v, ok := &lt;-ch:
    if !ok {
        ("Channel Close")
    } else {
        ("receive:", v)
    }
}

The behavioral characteristics of select

Behavior describe
Random Scheduling Randomly select one execution when multiple cases are available at the same time (prevent hunger)
Blocking and waiting When all cases block, select itself blocks
default branch All cases are blocked immediately to avoid blocking
Choose only one Only one of them is executed when multiple are satisfied at the same time

Work with goroutine: Producer/Consumer Model

func producer(ch chan int) {
    for i := 0; i &lt; 5; i++ {
        ch &lt;- i
    }
    close(ch)
}
​
func consumer(ch chan int, done chan struct{}) {
    for {
        select {
        case val, ok := &lt;-ch:
            if !ok {
                done &lt;- struct{}{}
                return
            }
            ("Consumption:", val)
        }
    }
}

select + for: Common loop writing methods

for {
    select {
    case msg := &lt;-ch:
        ("receive:", msg)
    case &lt;-(5 * ):
        ("Timeout Exit")
        return
    }
}

select Common traps

trap describe
Forgot default causes blockage If all cases block, select also blocks
Infinite blockage All channels in select will never be available
channel closed Write panic to closed channels, be careful
Timeout misuse When using (),Don't create new channels frequently in loops, otherwise the memory leaks

🔍 Solve Suggestions:useand multiplex the timer.

Practical advice

suggestion reason
Use select to implement timeout control More elegant and non-blocking
select + default implements non-blocking communication Avoid goroutine stuck
Use select + () to control exit More suitable for large systems

Example: context control exit (recommended production use)

ctx, cancel := ((), 3*)
defer cancel()
​
ch := make(chan int)
​
go func() {
    (2 * )
    ch &lt;- 42
}()
​
select {
case &lt;-():
    ("Operation Cancel/Timeout:", ())
case val := &lt;-ch:
    ("Received data:", val)
}

Summarize

Dimension illustrate
Function Implement multiplexed listening for channel
advantage Non-blocking, efficient and elegant communication control
Combined , context, default The best combination
Scene goroutine exit, task timeout, concurrent inter-coroutine communication control, etc.

This is the end of this article about select in Go language. For more detailed explanations of Go select, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!