Skip to content
Skill Authoring
Skill

/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 switches, and blank identifier patterns. Also use when writing a simple if/else or for loop, even if the user doesn't mention

BOOST
From plugin
golang-skills
18120 skills
Install
$ npx -y skills add cxuu/golang-skills --skill go-control-flow --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/go-control-flow

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when writing conditionals, loops, or switch statements in Go — including if with initialization, early returns, for loop forms, range, switch, type switches, and blank identifier patterns. Also use when writing a simple if/else or for loop, even if the user doesn't mention

SKILL.md

go-control-flow.SKILL.md
name: go-control-flow
description: Use when writing conditionals, loops, or switch statements in Go — including if with initialization, early returns, for loop forms, range, switch, type switches, and blank identifier patterns. Also use when writing a simple if/else or for loop, even if the user doesn't mention guard clauses or variable scoping. Does not cover error flow patterns (see go-error-handling).

Go Control Flow

Resource Routing

  • `references/SWITCH-PATTERNS.md` - Read when using switch statements, type switches, fallthrough, or labeled breaks.
  • `references/BLANK-IDENTIFIER.md` - Read when using `_`, blank imports, unused compile-time assertions, or intentional discards.

---

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:

1. The declaration is in the **same scope** as the existing `v` 2. The value is **assignable** to `v` 3. 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.

Route compile-time interface assertions to [go-interfaces](../go-interfaces/SKILL.md).

---

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 | Route to go-interfaces |

---

Related Skills

  • **Error flow**: See [go-error-handling](../go-error-handling/SKILL.md) when structuring guard clauses, early returns, or error-first patterns
  • **Type switches**: See [go-interfaces](../go-interfaces/SKILL.md) when using type switches, the comma-ok idiom, or interface satisfaction checks
  • **Nesting reduction**: See [go-style-core](../go-style-core/SKILL.md) when reducing nesting depth or resolving formatting questions
  • **Variable scoping**: See [go-declarations](../go-declarations/SKILL.md) when using if-init, `:=` redeclaration, or reducing variable scope
Read more
Ships withgolang-skills

AI Agent Skills for writing idiomatic, production-quality Go code. 20 modular skills teach AI coding assistants Go best practices derived from: Google Go Style Guide Effective Go Uber Go Style Guide Go Wiki CodeReviewComments Skills are tuned following

Get the whole plugin
Stats
181
Stars
19
Forks
Maintained
Maintenance
HTML
Language
Apache-2.0
License
4mo ago
Last commit
8mo ago
Created
2d ago
Added

Repo: cxuu/golang-skills

Other skills on golang-skills.