GO CONCURRENCY
Select & For Range Channel: Realizing What You May Not Know
Get a closer look at how ‘select’ and ‘for range’ work with Go channels. This guide highlights less-known behaviors and practical patterns, deepening your understanding of Go concurrency.
In our previous discussion, we covered five specific channel types in Go: buffered, unbuffered, directional, nil and closed channels.
If you missed that discussion, it’s important to note that we identified these types to provide a detailed understanding. Yet, at the most basic level, Go channels are primarily either buffered or unbuffered.
Now, we’re focusing on select
and for range
in Go.
1. Understanding select{}
Basically, the select
statement provides a mechanism for a goroutine to wait on multiple channels using the case statement and its main job is to execute the first case that is ready.
select {
case msg1 := <-ch1:
fmt.Println("Received", msg1)
case msg2 := <-ch2:
fmt.Println("Received", msg2)
}
a. How it works?
In the example above, the select
statement waits for either ch1
or ch2
to deliver data. When one of the channels is ready, the corresponding case executes.
“What happens if, by some chance, multiple cases are ready simultaneously?”
That’s where things get interesting, select doesn’t prioritize any case over others, instead, it makes an unbiased, random choice if more than one case is ready.
But.
There’s another aspect to consider, if a default
case is included in the select statement and none of the channels are ready, then the select does not wait, it quickly executes the default case:
select {
case msg1 := <-ch1:
fmt.Println("Received"…