Breakdown of “select” statement in Go

Suryansh Shrivastava
3 min readAug 23, 2023

--

Alright, lets take this great example to understand how the `select` statement works in Go. Let’s go step-by-step:

Channels Creation in main :

c := make(chan int)
quit := make(chan int)
  • c will be used for sending Fibonacci sequence numbers.
  • quit will be used to signal when to stop generating Fibonacci numbers.

2. Goroutine in main :

go func() {
for i := 0; i < 10; i++ {
fmt.Println(<-c)
}
quit <- 0
}()
  • This anonymous goroutine is started in the background.
  • It waits to receive 10 Fibonacci numbers from the channel `c` and prints them.
  • After printing 10 numbers, it sends a value (0 in this case, but the actual value isn’t used or checked) to the quit channel, signaling that it’s done.

3. fibonacci function :

  • It initializes two values `x` and `y` to `0` and `1`, the first two numbers in the Fibonacci sequence.
  • It enters an infinite `for` loop, and within this loop, there’s a `select` statement.

4. select Statement :

select {
case c <- x:
x, y = y, x+y
case <-quit:
fmt.Println("quit")
return
}
  • The `select` statement allows a goroutine to wait on multiple communication operations. It’s similar to a `switch` statement, but for channels.
  • The `select` will block until one of its cases can execute, then it will execute that case. If multiple cases could proceed, then one case is chosen at random to execute.
  • In this example, there are two cases:
    1. Sending the current Fibonacci number (`x`) to channel `c`.
    2. Receiving a value from the `quit` channel.

5. Working of the select :

  • If the main goroutine (specifically, the anonymous one) is ready to receive a value on `c`, the first case will execute: the current Fibonacci number (`x`) is sent over channel `c`, and then the next Fibonacci number is calculated.
  • If a value is sent on the `quit` channel (which happens after the anonymous goroutine has received and printed 10 Fibonacci numbers), the second case will execute, printing “quit” and then exiting the `fibonacci` function.

6. Back to the main function :

  • After starting the anonymous goroutine, `main` calls the `fibonacci` function directly.
  • The `fibonacci` function will keep generating numbers until it receives a signal on the `quit` channel.
  • Once “quit” is printed and the `fibonacci` function returns, the `main` function also finishes execution and the program ends.

Lets Visualise

Main Goroutine                      G1
| |
| starts G1 |
|----------------------------->|
| |
calls fibonacci() |
enters infinite loop |
waiting on channels |
| |
| |
| reads from c
| 10 times
| |
Main Goroutine                      G1
| |
| |
sends 0 to c |
|<-----------------------------|
| |
sends 1 to c |
|<-----------------------------|
| |
... |
... |
... |
... |
sends 34 to c |
|<-----------------------------|
| |
waits on select |
| |
| sends to quit
|<-----------------------------|
prints "quit" |
and exits fibonacci() |
| |
Main Goroutine ends |

In summary

The `select` statement provides a way to handle multiple channels simultaneously. The `fibonacci` function keeps generating Fibonacci numbers, but can be interrupted (and told to exit) by sending a value on the `quit` channel. The `main` function sets this all up, creating a goroutine that prints the first 10 Fibonacci numbers and then signals the generator to quit.

--

--

Suryansh Shrivastava

Protocol Engineer & Blockchain Developer | Go | Solidity | Move | Cross-Chain & Interop | Smart Contracts | Defi (AMM, Lending, Derivatives and Stable-coins)