Have any experienced Go devs found cases where this behavior is useful?
Have any experienced Go devs found cases where this behavior is useful?
select {
case foo := <-whateverCh:
log.Printf("hey a foo: %v", foo)
case <-ctx.Done():
log.Println("the user doesn't care about the answer anymore, so let's not leak the goroutine")
}In practice, in cases where a nil read/write could happen, a default "fall through" option on a select statement is used.
They could have made the original interface return a possible error for reading/writing, in line with regular go error handling, but opted instead to use more channel-based conventions.
Honestly, I see the ability to block indefinitely as a bug in the language. An improved language would probably "result, err := <(ctx)- ch", i.e. make it impossible to block without something bounding the duration of the block. (Also kill sync.Mutex. 100% of Go concurrency bugs are from people mixing mutexes and channels.)
(As an alternative, the runtime could be smarter about goroutines that have blocked forever. I am not sure exactly what it would look like, but the hypothetical first Go program I talk about above would probably be saved by something that killed goroutines that were waiting for a message from a TCP connection that is long gone. I think if it were easy to do right, it would have been done, though.)