GoLang Tutorial - Channels ("<-") with Select
Continued from Channels ("<-"), in this post, we'll learn how the select makes channels of Go powerful.
Combining goroutines and channels with select is a powerful feature of Go because select lets us wait on multiple channel operations.
There is a difference between switch and select:
- select: it is only used with channels. The select statement lets a goroutine wait on multiple communication operations. A select blocks until one of its cases can run, then it executes that case. It chooses one at random if multiple are ready.
- switch: it is used with concrete types. It goes in sequence and it is used to make a decision based on a variable value of any type.
We'll start from the following as a base code:
The code: select_base.go
The code creates a new channel with make(chan val-type)
. Channels are typed by the values they convey. Then, it starts to send a value into a channel using the channel <-
syntax.
The code produces of 10 Fibonacci number and then the receiver is told there are no more values coming from the sender (via close()), then the range loop is terminated.
Here is updated code with select statement. The code gives 5 Fibonacci numbers:
The code: fibonacci-with-select.go
Output:
There are couple of changes from the base code. This time, we make the anonymous function as a goroutine instead of making the fibonacci() as a goroutine. The fibonacci() function now gets two channels (c and q). Within the function it continues to calculate fibo numbers until it receives a value through q channel. Once the channel q receives a value it returns after printing "quit".
Note that the select blocks until one of its cases can run, then it executes that case. Also, note that our anonymous goroutine is the one finishes the fibonacci by sending 999 to the channel q.
Basic sends and receives on channels are blocking.
However, we can use select with a default clause to implement non-blocking sends, receives, and even non-blocking multi-way selects. The default case in a select is run if no other case is ready.
Actually, we've used a non-blocking receive:
case quit_value := <-quit:
If a value is available on q then select takes the <-quit case with that value.
Let's add the default clause to the code:
The code: fibonacci-with-select-and-default.go
Output:
We can see the code hit default multiple times.
Go Tutorial
- GoLang Tutorial - HelloWorld
- Calling code in an external package & go.mod / go.sum files
- Workspaces
- Workspaces II
- Visual Studio Code
- Data Types and Variables
- byte and rune
- Packages
- Functions
- Arrays and Slices
- A function taking and returning a slice
- Conditionals
- Loops
- Maps
- Range
- Pointers
- Closures and Anonymous Functions
- Structs and receiver methods
- Value or Pointer Receivers
- Interfaces
- Web Application Part 0 (Introduction)
- Web Application Part 1 (Basic)
- Web Application Part 2 (Using net/http)
- Web Application Part 3 (Adding "edit" capability)
- Web Application Part 4 (Handling non-existent pages and saving pages)
- Web Application Part 5 (Error handling and template caching)
- Web Application Part 6 (Validating the title with a regular expression)
- Web Application Part 7 (Function Literals and Closures)
- Building Docker image and deploying Go application to a Kubernetes cluster (minikube)
- Serverless Framework (Serverless Application Model-SAM)
- Serverless Web API with AWS Lambda
- Arrays vs Slices with an array left rotation sample
- Variadic Functions
- Goroutines
- Channels ("<-")
- Channels ("<-") with Select
- Channels ("<-") with worker pools
- Defer
- GoLang Panic and Recover
- String Formatting
- JSON
- SQLite
- Modules 0: Using External Go Modules from GitHub
- Modules 1 (Creating a new module)
- Modules 2 (Adding Dependencies)
- AWS SDK for Go (S3 listing)
- Linked List
- Binary Search Tree (BST) Part 1 (Tree/Node structs with insert and print functions)
- Go Application Authentication I (BasicAuth, Bearer-Token-Based Authentication)
- Go Application Authentication II (JWT Authentication)
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization