What does this print? (receiving from a closed buffered channel)
Question 186MediumGo 1.22 to 1.25
package main
import "fmt"
func main() {
ch := make(chan int, 3)
ch <- 1
ch <- 2
close(ch)
for i := range 4 {
v, ok := <-ch
fmt.Println(i, v, ok)
}
}
Output:
0 1 true
1 2 true
2 0 false
3 0 false
Closing a channel does not discard buffered values. Receivers drain the buffer with ok == true. Once it is empty, every receive returns immediately with the zero value and ok == false. This is why the comma-ok idiom (or for range) is the only reliable way to detect closure. Checking v == 0 is ambiguous because 0 might be a real value.
More on Channels & select
- Q184Describe the runtime internals of a channel (
hchan). - Q185Give the complete table of channel operation behavior for nil, open, and closed channels.
- Q187Explain the comma-ok idiom on channel receive. When is it needed and when is
for rangebetter? - Q188Who should close a channel, and why? What are the rules?
- Q189How do you safely close a channel that might be closed by multiple goroutines?
- Q190How does
selectchoose among multiple ready cases? Is it fair?