Skip to main content
skill CX Codex

go-control-flow — Claude Code skill: what it does, how to install

Teaches AI agents canonical Go control flow patterns: early returns, scoped if statements, and for loops. Keeps code flat and avoids variable shadowing bugs.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add cxuu/golang-skills --skill go-control-flow -a claude-code
Open on GitHub

What go-control-flow does

The skill instructs coding agents on idiomatic Go control flow. It enforces if statements with initialization statements to restrict variable scope and strips redundant else blocks when returning early. It covers all Go for loop forms, parallel assignments for two-pointer traversals, rune iteration over strings, and labeled breaks to exit loops from within a switch.

A key warning targets variable shadowing. Using := inside an inner block silently creates a new variable instead of reassigning the outer one. This frequently causes lost context updates. Error handling patterns are explicitly excluded here and redirected to go-error-handling.

What it helps with

  • flatten nested conditionals using guard clauses and early returns
  • break out of an outer loop from an inner switch statement
  • scope transient variables directly within if or switch initialization
  • prevent variable shadowing bugs caused by inner-scope := declarations

Example prompts for the agent

  • Refactor this nested if-else chain into clean Go guard clauses
  • Write a two-pointer reverse loop using Go parallel assignment
  • Check this switch statement inside a for loop for exit bugs

How to install go-control-flow

1Skills CLI (Vercel)

npx skills add cxuu/golang-skills --skill go-control-flow -a claude-code

2Manually: put the files in place

~/.claude/skills/go-control-flow/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/go-control-flow/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about go-control-flow

How do I install go-control-flow in Claude Code?

Run npx skills add cxuu/golang-skills --skill go-control-flow -a claude-code. The skill file is placed in ~/.claude/skills/go-control-flow/SKILL.md.

What does go-control-flow do?

It provides idiomatic guidance on Go control structures. It covers scoped initialization, range behaviors, labeled breaks, and avoiding accidental shadowing.

Does go-control-flow handle Go error patterns?

No. Error handling flow and early guard return patterns for errors are delegated to the separate go-error-handling skill.

Source text

SKILL.md · Apache-2.0
---
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:

```go
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:

```go
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:

```go
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:

```go
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:

```go
// 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`:

```go
// 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:

```go
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:

```go
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:

```go
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

© cxuu · Apache-2.0 · cxuu/golang-skills

Similar skills

All skills for Programming languages →

From the same set19

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor