SoFunction
Updated on 2025-04-14

Detailed explanation of select statements in Go language and working principle

What does select in Go do

In Go,selectA statement is a control structure used to handle multiple channels. It's similar toswitchStatements, but specifically used for concurrent programming, allow Goroutine to wait for operations (send or receive) on multiple channels and execute corresponding branches when a channel is ready.selectIt is one of the core features in the Go concurrency model and is closely related to channels and Goroutine.

Basic functions

selectThe main functions are:

  • Multiplexing channel: Listen to read and write operations of multiple channels at the same time.
  • Non-blocking selection: When any of the multiple channels is ready, the corresponding logic is executed; if no channel is ready, the default branch can be executed (if any).
  • Concurrent coordination: Helps Goroutine coordinate behavior in different communication scenarios.

grammar

select {
case <-channel1:
    // Processing logic when receiving data from channel1case channel2 <- value:
    // Processing logic when sending data to channel2case v := <-channel3:
    // Processing logic for receiving data from channel3 and assigning value to vdefault:
    // Default logic when all channels are not ready (optional)}
  • EachcaseIndicates a channel operation (send or receive).
  • defaultis optional, indicating the logic executed when all channels are not ready.

How it works

Wait for the channel to be ready

  • selectWill block the current Goroutine until a certaincaseThe channel operation in the process can be performed.
  • If multiple channels are ready at the same time,selectOne will be selected randomlycasePerform (avoid hunger problems).

Non-blocking behavior

  • If provideddefaultbranch, and no channel is ready,selectWill be executed immediatelydefaultWithout blocking.

Empty select

  • ifselectNone incase, will permanently block (similar tofor {})。

Example

Example 1: Listen to multiple channels

package main
import (
    "fmt"
    "time"
)
func main() {
    ch1 := make(chan string)
    ch2 := make(chan string)
    go func() {
        (1 * )
        ch1 <- "from ch1"
    }()
    go func() {
        (2 * )
        ch2 <- "from ch2"
    }()
    select {
    case msg1 := <-ch1:
        ("Received:", msg1)
    case msg2 := <-ch2:
        ("Received:", msg2)
    }
}
  • OutputReceived: from ch1
  • illustratech1After 1 second,ch2(2 seconds) fast, so executech1branch.

Example 2: With default branch

package main
import (
    "fmt"
)
func main() {
    ch := make(chan string)
    select {
    case msg := <-ch:
        ("Received:", msg)
    default:
        ("No message received")
    }
}
  • OutputNo message received
  • ​​​​​​​illustrate:becausechNo data ready,selectimplementdefaultBranch.

Example 3: Combination of sending and receiving

package main
import (
    "fmt"
    "time"
)
func main() {
    ch1 := make(chan string, 1)
    ch2 := make(chan string, 1)
    select {
    case ch1 <- "to ch1":
        ("Sent to ch1")
    case msg := <-ch2:
        ("Received from ch2:", msg)
    default:
        ("Nothing happened")
    }
}
  • OutputSent to ch1
  • ​​​​​​​illustratech1It is a buffer channel that can be sent immediately and successfully, so the send branch is executed.

Example 4: Timeout Control

package main
import (
    "fmt"
    "time"
)
func main() {
    ch := make(chan string)
    select {
    case msg := <-ch:
        ("Received:", msg)
    case <-(2 * ):
        ("Timeout after 2 seconds")
    }
}
  • OutputTimeout after 2 seconds
  • ​​​​​​​illustrateCreate a timer channel, ready in 2 seconds, simulates the timeout logic.

Common uses

Multiplexing

Choose the ready channel between multiple channels to avoid polling one by one.

Timeout processing

useImplement operation timeout.

Non-blocking check

passdefaultBranch checks if the channel is ready.

Coordinate Goroutine

In a concurrent task, the next operation is determined based on the channel status.

Things to note

Random selection

When multiplecaseWhen it is ready,selectSelect a random execution, not in order.

Obstructive

Nodefaulthour,selectWill block until a channel is ready.

Empty select

select {}

This will permanently block and is usually used for main Goroutine waiting.

Channel close

If a channel is closed, the receiving operation will immediately return a zero value, which may require additional logical judgment.

Summarize

  • What is itselectIt is a concurrent control statement in Go that is used to handle multi-channel operations.
  • do what: Listen to multiple channels, select the ready channel to execute corresponding logic, and support timeout and non-blocking operations.
  • Why use it: Simplify concurrent programming, improve code efficiency and readability.

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