The first example the channel needs to be closed because of the usage of the range
keyword. When range is used with a channel, it will continue to try to read from the channel until the channel is closed.
From http://golang.org/ref/spec#For_statements
[When using
range
for] ...channels, the iteration values produced are the successive values sent on the channel until the channel is closed. If the channel is nil, the range expression blocks forever.
Which means that you have to close the channel to exit the loop.
In the second example you are using the receive operator <-
. This operator will block until one item can be pulled out of the channel. Since there is one item waiting in the channel to be delivered, it will yield immediately. In this case, close is optional because there are no other blocking operations on the channel after that, so it's just as happy to stay "open".
See the channels section for more details...