Before this:Values, variables & types
Control flow
Key takeaways
Go keeps control flow tiny: if, for, and switch. There is no
while — the single for keyword does counted loops, condition loops, infinite
loops, and (with range) iteration over collections. A switch breaks after
each case by default, so there is no accidental fall-through. Small set, few
surprises.
This lesson covers every way Go changes the path a program takes. It builds on
Values, variables & types and sets up
Functions & error handling, where
if err != nil becomes the most-used branch in the language.
How does if work in Go?
An if needs no parentheses around its condition, and the braces are always
required:
if snr < 6.0 {
return errNoLock
}
Go adds one twist — an if can declare a variable scoped to the branch:
if peak := findPeak(fft); peak.Power > threshold {
tune(peak.FreqHz) // peak is visible here...
}
// ...and gone here.
This keeps short-lived values out of the surrounding scope, which is why you’ll see
if err := do(); err != nil { ... } everywhere in Go.
The one loop: for
Go has no while and no do. Everything loops with for, in three shapes:
for i := 0; i < 8; i++ { // classic counted loop
process(taps[i])
}
for scanning { // condition-only — this is Go's "while"
scanning = step()
}
for { // no condition — loop forever
sample := <-samples
handle(sample) // break or return to stop
}
To walk a slice, map, or channel, add range:
for i, s := range symbols { // index and value
decode(i, s)
}
for freq := range channels { // map: keys
tune(freq)
}
range over a channel receives until it is closed — the pattern GopherTrunk’s
sample pipeline uses to drain a stream of complex64 values.
What makes Go’s switch different?
A switch is a cleaner chain of if/else. Crucially, each case breaks
automatically — no break needed, no accidental fall-through:
switch mode {
case "P25":
decodeP25(frame)
case "DMR", "NXDN": // one case, several values
decodeTDMA(frame)
default:
log.Printf("unknown mode %q", mode)
}
You can also omit the value and use switch as a tidy if-chain:
switch {
case snr > 20:
quality = "excellent"
case snr > 8:
quality = "usable"
default:
quality = "no lock"
}
The table below sums up the whole toolkit.
| Construct | Shape | Use it for |
|---|---|---|
if / else |
if cond { } |
A one-off branch, often if err != nil |
for (counted) |
for i := 0; i < n; i++ |
A known number of iterations |
for (condition) |
for cond { } |
Go’s while loop |
for (infinite) |
for { } |
Loop until break/return |
for range |
for k, v := range x |
Walking slices, maps, channels |
switch |
switch x { case … } |
Many branches on one value |
Quick check: how do you write a while loop in Go?
Recap
ifneeds no parentheses and can declare a branch-scoped variable.foris Go’s only loop — counted, condition (itswhile), infinite, orrange.rangewalks slices, maps, and channels.switchbreaks after each case by default;fallthroughis opt-in and rare.
Next up: functions, multiple return values, and Go’s error type.
Frequently asked questions
Does Go have a while loop?
No — and it doesn’t need one. Go has exactly one loop keyword, for, and it covers every case: for cond {} is a while loop, for {} is an infinite loop, and for i := 0; i < n; i++ {} is the classic counted loop. One keyword, three shapes.
Does a Go switch fall through to the next case?
No. Unlike C, each Go case breaks automatically — there is no accidental fall-through. If you genuinely want the next case to run too, you add an explicit fallthrough statement, which is rare.