Concurrency · 3 MIN READ
The sender closes, the receiver ranges
Decide who closes a channel, and why the other side must not.
Closing a channel says that no more values will be sent. Give that decision to the producer, or to a coordinator that knows all producers have finished. A receiver should not close a stream while senders may still use it.
Receivers can drain a closed buffered channel. v, ok := <-ch reports false only when the channel is closed and empty; for v := range ch then ends. Sending after close and closing twice both panic.
SEE THE IDEA
The sender announces that no more values are coming
- 01
Produce
goch <- valueSend every value first
- 02
Finish
goclose(ch)Signal the end of production
- 03
Drain
gofor v := range chRead remaining values, then stop
Close is a statement about the stream ending, not about discarding its queued values.
In practice
Give exactly one owner responsibility for closing. If multiple workers send, a coordinator can wait for all of them and close the results channel afterward. Receivers normally do not close because they cannot know that every sender has finished.
Watch out
Sending to a closed channel or closing it twice panics. A channel used only for coordination does not always need to be closed.
Work through the exercise
package main
// squares should send each square and then let the consumer's range
// loop finish on its own.
func squares(n int) <-chan int {
out := make(chan int)
go func() {
for i := 1; i <= n; i++ {
out <- i * i
}
}()
return out
}
func main() {}Trace each value and write down your reasoning. Copy the source into GopherForge or your local Go environment to compile and check it. This web page does not execute your code or send it to a compiler service.
Progress stays in this browser. No account needed.