go-control-flow▌
cxuu/golang-skills · updated Apr 8, 2026
Read references/SWITCH-PATTERNS.md when using switch statements, type switches, or break with labels
Go Control Flow
Read references/SWITCH-PATTERNS.md when using switch statements, type switches, or break with labels
Read references/BLANK-IDENTIFIER.md when using
_, blank identifier imports, or compile-time interface checks
If with Initialization
if and switch accept an optional initialization statement. Use it to scope
variables to the conditional block:
if err := file.Chmod(0664); err != nil {
log.Print(err)
return err
}
If you need the variable beyond a few lines after the if, declare it
separately and use a standard if instead:
x, err := f()
if err != nil {
return err
}
// lots of code that uses x
Indent Error Flow (Guard Clauses)
When an if body ends with break, continue, goto, or return, omit the
unnecessary else. Keep the success path unindented:
f, err := os.Open(name)
if err != nil {
return err
}
d, err := f.Stat()
if err != nil {
f.Close()
return err
}
codeUsing(f, d)
Never bury normal flow inside an else when the if already returns.
Redeclaration and Reassignment
The := short declaration allows redeclaring variables in the same scope:
f, err := os.Open(name) // declares f and err
d, err := f.Stat() // declares d, reassigns err
A variable v may appear in a := declaration even if already declared,
provided:
- The declaration is in the same scope as the existing
v - The value is assignable to
v - At least one other variable is newly created by the declaration
Variable Shadowing
Warning: If v is declared in an outer scope, := creates a new
variable that shadows it — a common source of bugs:
// Bug: ctx inside the if block shadows the outer ctx
if *shortenDeadlines {
ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
defer cancel()
}
// ctx here is still the original — the shadowed ctx didn't escape
// Fix: use = instead of :=
var cancel func()
ctx, cancel = context.WithTimeout(ctx, 3*time.Second)
For Loops
Go's for is its only looping construct, unifying while, do-while, and
C-style for:
// Condition-only (Go's "while")
for x > 0 {
x = process(x)
}
// Infinite loop
for {
if done() { break }
}
// C-style three-component
for i := 0; i < n; i++ { ... }
Range
range iterates over slices, maps, strings, and channels:
for i, v := range slice { ... } // index + value
for k, v := range myMap { ... } // key + value (non-deterministic order)
for i, r := range "héllo" { ... } // byte index + rune (not byte)
for v := range ch { ... } // receives until channel closed
Key rules:
- Range over strings yields runes, not bytes —
iis the byte offset - Range over maps has non-deterministic order — don't rely on it
- Use
_to discard the index or value:for _, v := range slice
Parallel Assignment
Go has no comma operator. Use parallel assignment for multiple loop variables:
for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
a[i], a[j] = a[j], a[i]
}
++ and -- are statements, not expressions — they cannot appear in parallel
assignment.
Switch: Labeled Break
break inside a switch within a for loop only breaks the switch.
Use a labeled break to exit the enclosing loop:
Loop:
for _, v := range items {
switch v.Type {
case "done":
break Loop // breaks the for loop
}
}
For type switches, see go-interfaces: Type Switch.
The Blank Identifier
Never discard errors carelessly — a nil dereference panic may follow.
Verify interface compliance at compile time: var _ io.Writer = (*MyType)(nil).
See go-interfaces for the interface satisfaction check pattern.
Quick Reference
| Pattern | Go Idiom |
|---|---|
| If initialization | if err := f(); err != nil { } |
| Early return | Omit else when if body returns |
| Redeclaration | := reassigns if same scope + new var |
| Shadowing trap | := in inner scope creates new variable |
| Parallel assignment | i, j = i+1, j-1 |
| Expression-less switch | switch { case cond: } |
| Comma cases | case 'a', 'b', 'c': |
| No fallthrough | Default behavior (explicit fallthrough if needed) |
| Break from loop in switch | break Label |
| Discard value | _, err := f() |
| Side-effect import | import _ "pkg" |
| Interface check | var _ Interface = (*Type)(nil) |
Related Skills
- Error flow: See go-error-handling when structuring guard clauses, early returns, or error-first patterns
- Type switches: See go-interfaces when using type switches, the comma-ok idiom, or interface satisfaction checks
- Nesting reduction: See go-style-core when reducing nesting depth or resolving formatting questions
- Variable scoping: See go-declarations when using if-init,
:=redeclaration, or reducing variable scope
Discussion
Product Hunt–style comments (not star reviews)- No comments yet — start the thread.
Ratings
4.7★★★★★60 reviews- ★★★★★Isabella Gonzalez· Dec 20, 2024
Registry listing for go-control-flow matched our evaluation — installs cleanly and behaves as described in the markdown.
- ★★★★★Liam Khanna· Dec 16, 2024
go-control-flow reduced setup friction for our internal harness; good balance of opinion and flexibility.
- ★★★★★Ava Rao· Dec 16, 2024
go-control-flow is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
- ★★★★★Li Zhang· Dec 8, 2024
Useful defaults in go-control-flow — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
- ★★★★★Layla Liu· Dec 4, 2024
go-control-flow has been reliable in day-to-day use. Documentation quality is above average for community skills.
- ★★★★★Zara Mensah· Nov 27, 2024
Registry listing for go-control-flow matched our evaluation — installs cleanly and behaves as described in the markdown.
- ★★★★★Yusuf Menon· Nov 23, 2024
go-control-flow fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
- ★★★★★Advait White· Nov 11, 2024
Useful defaults in go-control-flow — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
- ★★★★★Arya Johnson· Nov 7, 2024
I recommend go-control-flow for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
- ★★★★★Layla Farah· Nov 3, 2024
Keeps context tight: go-control-flow is the kind of skill you can hand to a new teammate without a long onboarding doc.
showing 1-10 of 60