SuperAPI AI Directory

go-dev

Coding & development

View repository

Updated 10-30 16:18

About this skill

Related Skills

  • go-setup - Project initialization and library selection
  • go-fluent-testing - Unit/integration/E2E testing (fluent Given/When/Then)

References

Deep-dive topics are split into focused reference files:

  • Interfaces - Inline interface definition, small focused interfaces, functional options
  • Error Handling - Golden rules, wrapping, sentinel errors, multi-error handling
  • Concurrency - errgroup, worker pools, channel patterns
  • Generics - Type parameters, constraints, data structures, decision framework
  • Testing - Table-driven tests, mocks, benchmarks, fuzzing
  • Performance & Footguns - Pre-allocation, sync primitives, common pitfalls
Quick Reference Tables

Error Handling

✅ Do This ❌ Never This
errors.Is(err, ErrX) err == ErrX
errors.As(err, &target) err.(*Type)
fmt.Errorf("...: %w", err) fmt.Errorf("...: %v", err)
errors.Join(errs...) Manual error collection

Concurrency

✅ Do This ❌ Never This
errgroup.WithContext(ctx) Bare sync.WaitGroup
g.SetLimit(n) Unbounded goroutines
Loop variable capture Range variable in goroutine
Context for cancellation Global done channels

Testing

Race detection is mandatory for concurrent code; coverage and benchmarks follow the same go test flags as any Go project.

Go embedding

Embedding promotes the embedded struct's members onto the outer type. NEVER re-bind the host inside a method (p := c.parts is always wrong): call promoted members on the receiver directly (c.require, c.parsedFile, c.aClient()). A hop is justified ONLY when passing the host as a value. Never build a bidirectional cycle (base embeds sub-structs while sub-structs embed base) - shape promotion one-way. Full rules: references/performance.md §Go embedding.

No var _ = []any{ Type{} } compile-assert blocks (or var _ unused-import silencers) - dead noise; delete and let unused name genuinely dead symbols. Full rule: references/performance.md §No lint-appeasement constructs.

Design acceptance is a gate

Gates (build/vet/lint/tests/parity) verify code correctness: none of them verifies the user accepts the design. A structural/topology change (file layout, struct shapes, DSL patterns) gets user sign-off on ONE probe file before mass application: wave-by-wave shipping of an unconfirmed pattern converts every review into a rewrite. Each stored design rule carries its as-of date; when the user signals the shape is wrong, re-read the rule from scratch instead of re-applying the stored one.

Fluent-chain shape (Go DSL structs)

A fluent builder chain survives promotion only while every builder returns the SAME concrete type. Prefer ONE struct holding all state with methods on *parts-style receivers returning that pointer: mixed-domain chains and .and() links then work with zero call-site churn. Before adding wrapper structs, generic self-types, or per-domain return types, prototype the WORST chain in a scratch module (go mod init + one test) and check cross-domain links compile: self-typed generics (parts[S]) break chains the moment a method from another domain is called, and a *parts receiver cannot soundly return a domain-typed S (zero value = nil). Go 1.27 generic methods don't fix this. Wrapper-marker structs (stateless type X struct { base }) add ctor ceremony without behavior; if state is already flat, they get deleted on the next simplification pass.