go-control-flow

Use when writing conditionals, loops, or switch statements in Go — including if with initialization, early returns, for loop forms, range, switch, type…

INSTALLATION
npx skills add https://github.com/cxuu/golang-skills --skill go-control-flow
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

$27

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 — i is 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
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card