Golang-skills go-declarations
Use when declaring or initializing Go variables, constants, structs, or maps — including var vs :=, reducing scope with if-init, formatting composite literals, designing iota enums, and using any instead of interface{}. Also use when writing a new struct or const block, even if the user doesn't ask about declaration style. Does not cover naming conventions (see go-naming).
git clone https://github.com/cxuu/golang-skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/cxuu/golang-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/go-declarations" ~/.claude/skills/cxuu-golang-skills-go-declarations && rm -rf "$T"
skills/go-declarations/SKILL.mdGo Declarations and Initialization
Quick Reference: var vs :=
| Context | Use | Example |
|---|---|---|
| Top-level | (always) | |
| Local with value | | |
| Local zero-value (intentional) | | |
| Type differs from expression | with type | |
Read references/SCOPE.md when deciding between var and := in complex initialization patterns or multi-return assignments.
Group Similar Declarations
Group related
var, const, type in parenthesized blocks. Separate
unrelated declarations into distinct blocks.
// Bad const a = 1 const b = 2 // Good const ( a = 1 b = 2 )
Inside functions, group adjacent vars even if unrelated:
var ( caller = c.name format = "json" timeout = 5 * time.Second )
Constants and iota
Start enums at one so the zero value represents invalid/unset:
const ( Add Operation = iota + 1 Subtract Multiply )
Use zero when the default behavior is desirable (e.g.,
LogToStdout).
Read references/IOTA.md when designing iota enums with bitmask patterns, byte-size constants, or String() methods.
Variable Scope
Use if-init to limit scope when the result is only needed for the error check:
if err := os.WriteFile(name, data, 0644); err != nil { return err }
Don't reduce scope if it forces deeper nesting or you need the result outside the
if. Move constants into functions when only used there.
Read references/SCOPE.md when working with top-level declarations or choosing between var and := for local variables.
Initializing Structs
- Always use field names (enforced by
). Exception: test tables with ≤3 fields.go vet - Omit zero-value fields — let Go set defaults.
- Use
for zero-value structs:var
notvar user Useruser := User{} - Use
over&T{}
:new(T)sptr := &T{Name: "bar"}
Read references/STRUCTS.md when initializing structs with many fields, building slices of struct pointers, or choosing single-line vs multi-line format.
Composite Literal Formatting
Use field names for external package types. Match closing brace indentation with the opening line. Omit repeated type names in slice/map literals (
gofmt -s).
Read references/INITIALIZATION.md when working with complex composite literals, cuddled braces, or zero-value field decisions.
Read references/LITERALS.md when formatting complex composite literals.
Initializing Maps
| Scenario | Use | Example |
|---|---|---|
| Empty, populated later | | |
| Nil declaration | | |
| Fixed entries at init | Literal | |
make() visually distinguishes empty-but-initialized from nil. Use size hints
when the count is known.
Raw String Literals
Use backtick strings to avoid hand-escaped characters:
// Bad wantError := "unknown name:\"test\"" // Good wantError := `unknown name:"test"`
Ideal for regex, SQL, JSON, and multi-line text.
Prefer any
Over interface{}
anyinterface{}Go 1.18+: use
any instead of interface{} in all new code.
Avoid Shadowing Built-In Names
Never use predeclared identifiers (
error, string, len, cap, append,
copy, new, make, close, delete, panic, recover, any, true,
false, nil, iota) as names. Use go vet to detect.
// Bad — shadows the builtin var error string // Good var errorMessage string
Read references/SHADOWING.md when debugging issues where := creates new variables that shadow outer scope.
Related Skills
- Naming conventions: See go-naming when choosing variable names, constant names, or deciding name length by scope
- Data structures: See go-data-structures when choosing between
andnew
, or initializing slices and mapsmake - Control flow scoping: See go-control-flow when using if-init,
redeclaration, or avoiding variable shadowing:= - Capacity hints: See go-performance when pre-allocating maps or slices with known sizes