# Idiomatic Go (Effective Go) — Claude Code rules Write Go the way the standard library does. These rules are style and idiom, per *Effective Go* and the official *Go Code Review Comments*. (For stdlib-first library choices, see the `go-stdlib` pack — this pack complements it.) ## Formatting - Run `gofmt` (or `go fmt`) on all code; it is the canonical format, not a preference. If a layout looks wrong after `gofmt`, rearrange the code rather than fight the tool. - Tabs for indentation, not spaces. No line-length limit — if a line feels long, wrap it and indent with an extra tab. - Control structures (`if`, `for`, `switch`) take no parentheses. The opening brace stays on the same line as the statement. - Don't write explicit semicolons; the lexer inserts them. ## Naming - Use `MixedCaps` / `mixedCaps`, never underscores or `SCREAMING_CASE`. An unexported constant is `maxLength`, not `MAX_LENGTH`. - Visibility is by case: an upper-case first letter exports a name, lower-case keeps it package-private. - Package names are short, lower-case, single words — no underscores, no mixedCaps. Avoid meaningless names like `util`, `common`, `misc`, `types`. Callers qualify with the package, so don't stutter: `chubby.New`, not `chubby.NewChubby`. - No `Get` prefix on getters. The getter for field `owner` is `Owner()`; the setter is `SetOwner()`. - One-method interfaces take an `-er` suffix: `Reader`, `Writer`, `Formatter`. Match canonical method signatures (`Read`, `Write`, `Close`, `String`) when your type does the same job. - Initialisms keep a consistent case: `ServeHTTP` (not `ServeHttp`), `appID` (not `appId`), `URL`, `xmlHTTPRequest`. - Keep variable names short; closer to their declaration, the shorter they can be. Prefer `i` to `sliceIndex`, `c` to `lineCount`. ## Errors - Error strings are not capitalized (unless they start with a proper noun or acronym) and do not end with punctuation — they're usually printed inside other context: `fmt.Errorf("something bad")`, not `"Something bad."`. - When feasible, prefix error strings with the operation or package that generated them (e.g. `"image: unknown format"`). - Handle every error — return it, handle it, or (truly exceptionally) panic. Never discard errors with `_`. - Don't `panic` for normal error handling; use `error` and multiple return values. - Avoid in-band error values like `-1`, `nil`, or `""`. Return an extra `error` or `ok bool` instead (the comma-ok idiom). - Keep the happy path at minimal indentation: check the error, `return` early, and let the rest flow down the page. Omit the `else` after a terminating `if`. ## Interfaces - Keep interfaces small; one- or two-method interfaces are the norm. - Accept interfaces, return concrete types. Functions take interface params for flexibility; constructors return the concrete struct/pointer. - Define an interface in the package that *uses* it, not the implementor. Don't define interfaces before they're used, and don't add them "for mocking" — test through the real implementation's public API. - Compose with embedding (`type ReadWriter interface { Reader; Writer }`). ## Concurrency - "Do not communicate by sharing memory; instead, share memory by communicating." Pass values over channels rather than guarding shared state. - Use unbuffered channels to synchronize; `select` to multiplex; `make` to create channels, slices, and maps. - Pass `context.Context` as the first parameter of functions that need it: `func F(ctx context.Context, …)`. - Prefer synchronous functions (return results directly) over asynchronous ones. ## Other idioms - Receiver names are a 1–2 letter abbreviation of the type (`c` for `Client`), consistent across all methods. Never `me`, `this`, or `self`. - Use a pointer receiver to mutate, for large structs, or when the struct holds a `sync.Mutex`; value receivers for small immutable types. When in doubt, use a pointer. - `defer` cleanup (e.g. `f.Close()`) right after acquiring the resource; deferred calls run LIFO. - `new(T)` returns a zeroed `*T`; `make` initializes slices, maps, and channels. - Doc comments are full sentences that begin with the name and end with a period: `// Encode writes the JSON encoding of req to w.` - For keys or secrets use `crypto/rand`, never `math/rand`. ## Don't - Don't reformat against `gofmt` or hand-tune whitespace. - Don't name results just to enable naked returns — clarity beats a saved line. - Don't capitalize or punctuate error strings. - Don't return interfaces where a concrete type will do. - Don't reach for `panic` as control flow.