Go's typed pipes — communicate, don't share memory.
select
select is like switch — but for channel operations. Each case is either a
send or a receive on some channel. select blocks until one of them can proceed,
then runs that case. If multiple are ready, it picks one randomly.
A first select
Timeouts with time.After
time.After(d) returns a channel that delivers the current time after d. Drop
it into a select and you've got a timeout:
For real code, prefer context.WithTimeout (see chapter 20) over manual time.After.
Non-blocking with default
A default case runs when no other case is ready. Use it for non-blocking sends
and receives.
select {
case work := <-jobs:
process(work)
default:
// no work right now — do something else
}
select {} — block forever
A select with no cases blocks forever. Useful in main when all the real work
is in goroutines.
func main() {
go serve()
select {} // sit here until something kills us
}
Disabling a case at runtime
A nil channel never fires in a select — its case is silently skipped. This
lets you turn cases on and off dynamically:
var input <-chan job = jobs // active
if shuttingDown {
input = nil // disable this case
}
select {
case j := <-input:
process(j)
case <-ctx.Done():
return
}