Go's typed pipes — communicate, don't share memory.
Buffered Channels, range, and close
Buffered channels
make(chan T, n) creates a channel that holds up to n values without a
receiver. Sends only block when the buffer is full; receives only block when it's
empty.
Buffered channels are useful when:
- a producer is bursty and you don't want it to block,
- you want a fixed-size work queue between producers and workers,
- you're implementing a rate limiter.
But: don't reach for a buffered channel just to "avoid deadlock". If you need a buffer to make your code not hang, you probably have a synchronization bug.
Closing a channel
close(ch) tells "no more values will ever be sent on this channel". Receivers
can use the two-value form to detect closure:
v, ok := <-ch
if !ok {
// channel was closed and drained
}
Or — much more commonly — they use for ... range:
Channel rules of thumb
- Only the sender should close a channel. Sending on a closed channel panics; receiving from a closed channel returns the zero value immediately.
- If you have multiple senders, you'll need an extra signal (like another channel) to coordinate the close.
- Receivers don't need to close — they just stop reading.
- A
nilchannel blocks forever on both send and receive. Useful withselect.
| Operation | Result |
| ------------------------- | ----------------------------------------------- |
| Send on a closed channel | panic |
| Send on a nil channel | blocks forever |
| Receive on a closed channel | zero value immediately, ok==false |
| Receive on a nil channel | blocks forever |
| Close a closed channel | panic |
| Close a nil channel | panic |