Concurrency · 3 MIN READ
range over a channel ends when it closes
Drain a channel with range, and close it from the sender.
The Tour's "Range and Close" page: v, ok := <-ch sets ok to false once the channel is closed and empty. for v := range ch is that loop written once. Only the sender closes. Sending after a close panics. Closing is not required for the garbage collector — only for telling a range there is nothing more.
Channels are not files. Most of them never close, because nobody is ranging. Close when a range (or an ok-receive) needs the signal.
SEE THE IDEA
The receiver drains before the loop ends
- 01
Queue
goch <- valueValues may already be buffered
- 02
End production
goclose(ch)No new sends are allowed
- 03
Drain and stop
gofor v := range chEnds after the buffer is empty
A closed channel may still contain unread values.
In practice
Use range when the entire stream should be consumed until its producer finishes. If cancellation is also required, use a select loop and inspect the two-result receive. Assign close ownership to the producer or the coordinator that knows all producers are done.
Watch out
Ranging over a nil channel blocks forever. A never-closed stream also never ends by itself.
Work through the exercise
package main
// Drain reads every value until ch closes and returns them in
// the order they arrived.
func Drain(ch <-chan int) []int {
return nil
}
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.