Single Case Select
ID |
go.single_case_select |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Code Smell |
Language |
Go |
Tags |
code-style, concurrency |
Description
Reports a select statement that has exactly one communication case and no default clause.
A single-case select blocks on one channel operation, which is identical to performing that
operation directly.
Rationale
select exists to wait on several channel operations at once, or — with a default — to attempt
one without blocking. A select with a single case and no default does neither: it simply
blocks on that one operation, so v := ←ch says the same thing with less ceremony. The wrapper
is usually a leftover from a version that once had multiple cases, and it hides the intent.
// FLAW — equivalent to `v := <-ch`
select {
case v := <-ch:
use(v)
}
// OK — the default makes this a non-blocking receive
select {
case v := <-ch:
use(v)
default:
// nothing ready
}
Remediation
Replace the single-case select with the channel operation it wraps (v := ←ch). Keep the
select only when there is more than one case, or when a default clause provides non-blocking
behaviour.