What does this print? (select with a closed channel and a nil channel)
Question 193HardGo 1.22 to 1.25
package main
import "fmt"
func main() {
var nilCh chan int
closed := make(chan int)
close(closed)
counts := map[string]int{}
for range 1000 {
select {
case <-nilCh:
counts["nil"]++
case <-closed:
counts["closed"]++
default:
counts["default"]++
}
}
fmt.Println(counts)
}
It prints map[closed:1000]. The nil-channel case is never ready. The closed channel is always ready (returning the zero value), and default runs only when no case is ready. So the closed case wins all 1000 times. The random choice only applies among cases that are ready, and here only one is.
A follow-up interviewers often ask: "What if you delete default and closed?" Then the select waits on a nil channel only, which is equivalent to select {}. The main goroutine blocks forever, and the program crashes with fatal error: all goroutines are asleep - deadlock!
More on Channels & select
- Q191How do you implement a priority select in Go?
- Q192Why is a nil channel useful in a
select? Show an example. - Q194What causes "fatal error: all goroutines are asleep - deadlock!" and when does Go fail to detect a deadlock?
- Q195What does this program do? (unbuffered send in main)
- Q196How does
for rangeover a channel work, and what are its pitfalls? - Q197What are directional channel types and why use them?