Select statement in Golang

Golang select statement is like the switch statement, which is used for multiple channels operation. This statement blocks until any of the cases provided are ready. This post will explore the select statement in the Go programming language.

Golang Select Statement Syntax

The syntax of the select statement is like the switch statements. It is really easy to work with.

select {
	case case1:
		// case 1...
	case case2:
		// case 2...
	case case3:
		// case 3...
	case case4:
		// case 4...
	default:
                // default case...
}

Let’s see an example of a select statement.

Select Statement Example

Here is an example of a select statement that shows how it works. Select statements work like switch statements but instead of having concrete cases it has operations that are either sending or receiving using channels.

package main

import (
	"fmt"
)

func g1(ch chan int) {
	ch <- 12
}

func g2(ch chan int) {
	ch <- 32
}

func main() {

	ch1 := make(chan int)
	ch2 := make(chan int)

	go g1(ch1)
	go g1(ch2)

	select {
	case v1 := <-ch1:
		fmt.Println("Got: ", v1)
	case v2 := <-ch2:
		fmt.Println("Got: ", v2)
	}
}

When we run the program we get:

Go Select Output
Go Select Output

The output we got is totally dependent on what was executed then. It is simply random. We cannot predict the output since select works in a very different way. It chooses any output if all of the statements are ready for execution.

The default case in select statement

The default case is executed if none of the other cases are ready for execution. It prevents the select from blocking the main goroutine since the operations are blocking by default.

package main

import (
	"fmt"
)

func g1(ch chan int) {
	ch <- 42
}

func g2(ch chan int) {
	ch <- 43
}

func main() {

	ch1 := make(chan int)
	ch2 := make(chan int)

	go g1(ch1)
	go g1(ch2)

	select {
	case v1 := <-ch1:
		fmt.Println("Got: ", v1)
	case v2 := <-ch2:
		fmt.Println("Got: ", v2)
	default:
		fmt.Println("The default case!")
	}
}

In the above program, the default case gets printed due to the fact that the goroutines don’t get enough time to produce the output. So, the default gets printed.

Go Select Default Case
Go Select Default Case

Now, we can try sleeping the main thread and the output will be completely different.

Go Select Default Case Not Executed
Go Select Default Case Not Executed

This shows that the select entirely chooses the execution case based on what occurs first or simply what it gets first.

The empty select statement

When we use empty select statements inside a program the select statement blocks forever since no goroutine is available to provide any data. So, the main goroutine throws a panic and stops the deadlock.

package main

func main() {
	select {}
}

The output becomes something like this:

Go Empty Select
Go Empty Select

Uses of the select statement in Go

The select statement is used when multiple goroutines are sending data via channels then the select statement receives data concurrently and chooses the case randomly if all are ready. If no case is ready then it simply outputs the default case if the default case is already provided before. This shows the versatility of the select statement which is used to selectively get data from multiple provider channels.