A default case in a Go select is chosen only when no other case is ready. It makes the select nonblocking, rather than waiting for a channel operation. section 9.4
A common mistake is treating select cases as source-ordered. When several channel operations are ready, Go chooses among them randomly; default does not automatically lose by appearing later. section 9.4
Drain remaining messages after disconnection
After receiving from disconnectCh, an inner select can repeatedly receive from messageCh. It handles every currently available message, then takes default and returns when messageCh has none ready. Messages sent after the goroutine returns can still be missed. section 9.4
for {
select {
case v := <-messageCh:
fmt.Println(v)
case <-disconnectCh:
for { #1
select {
case v := <-messageCh: #2
fmt.Println(v)
default: #3
fmt.Println("disconnection, return")
return
}
}
}
}
The nested select shows the practical pattern: receive available messages through the channel case, then use default to stop without blocking. section 9.4

