Creating channels
May 18, 2023
Channel types
…
A new, initialized channel value can be made using the built-in function
make
, which takes the channel type and an optional capacity as arguments:make(chan int, 100)
Here we have the semi-magical make
built-in function again. We’ve already seen it for use with arrays and slices. Consider this yet another clue that a channel
is just another type, similar to array
and slice
, in that it “just” holds a bunch of values, and isn’t magical in any way.
The capacity, in number of elements, sets the size of the buffer in the channel. If the capacity is zero or absent, the channel is unbuffered and communication succeeds only when both a sender and receiver are ready. Otherwise, the channel is buffered and communication succeeds without blocking if the buffer is not full (sends) or not empty (receives). A
nil
channel is never ready for communication.
I find this description to unnecessarily call out unbuffered channels as seeming like a special case. They really aren’t.
The rules when it comes to whether or not a send or receive operation blocks is simple:
- A send to a channel blocks if there is no spare capacity to receive the new element.
- A receive from a channel blocks if there are no elements on the channel to be received.
This means that:
- Sending to a cahnnel with capacity 10, and 9 or fewer elements in it, will not block.
- Sending to a channel with capacity 10, and with 10 elements in it, will block until one of the elements is read.
- Sending to a channel with capacity 0 will block until that same element is read.
- Sending to a
nil
channel will block forever. - Receiving from a channel with capacity 10 and 1 or more elements in it will not block.
- Receiving from a channel with capacity 10 and 0 elements in it will block until an element is sent.
- Receiving from a channel with capacity 0 will block until an element is sent.
- Recieving from a
nil
channel will block forever.
Quotes from The Go Programming Language Specification Version of December 15, 2022