Go provides built-in support for concurrency. Channels in Go are a way to pass data between Go routines.
Nil channels are channels which have a nil value. With a nil channel, it won't be able to send nor receive values. This can prove useful when you want to block the process. When use with select
statement, it can allow you to ignore the nil channel, because it won't be able to receive any value, therefore allowing the select statement to select other channel cases.
Below is an example of one use case of a nil channel:
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// timeChannel is a channel that will receive current time after 2 seconds.
timeChannel := time.After(2000 * time.Millisecond)
// itemChannel is a nil channel. It won't be able to send or receive string.
var itemChannel chan string
var anItem string
sliceOfItems := []string{}
if len(sliceOfItems) > 0 {
log.Println("sliceOfItems is not empty")
// Initialise the itemChannel, so that now it can send and receive string.
itemChannel = make(chan string)
anItem = sliceOfItems[0]
// Go routine to send anItem into itemChannel.
go func() {
itemChannel <- anItem
}()
}
select {
case <-timeChannel:
// Will run after 2 seconds.
log.Println("select: <-timeChannel")
case item := <-itemChannel:
// Will run if sliceOfItems is not empty.
log.Println("select: itemChannel <- anItem")
log.Println("item:", item)
}
log.Println("DONE")
In the example, we've got 2 channels: timeChannel
and itemChannel
. timeChannel is a channel of type chan Time
which after the specified time (2 seconds in the example) will receive the current time. itemChannel is a channel of type chan string
and is use to send and receive string values.
The example, shows that itemChannel
is initialised as a nil channel with var itemChannel chan string
. When it's a nil channel, it won't be able to send nor receive string. It will however be made "un-nil" only when the slice: sliceOfItems
is not empty, so that an item from the slice can be send into the channel.
When the example code is run, you'll see that only the timeChannel
select case is run after 2 seconds. This is because the itemChannel
is currently nil, and it can't send nor receive string, therefore it's blocked in the select statement. This allows the timeChannel
to be selected after 2 seconds.
If you add an element to the slice: sliceOfItems, you'll see that the itemChannel
is selected instead of the timeChannel
.
I hope you've enjoyed this little snippets of code. This is only one of the many concurrency patterns for Go, and I encourage you to look into them, as will I.