AgentSkillsCN

go-best-practices

融合 Google、Uber 以及官方 Go 文档的最佳实践与风格指南。在编写、审查或重构 Go 代码时,此技能应被优先选用。它会在涉及 Go 包、错误处理、并发编程、接口定义,或性能优化等任务时自动触发。

SKILL.md
--- frontmatter
name: go-best-practices
description: Go style and best practices guide synthesized from Google, Uber, and official Go documentation. This skill should be used when writing, reviewing, or refactoring Go code. Triggers on tasks involving Go packages, error handling, concurrency, interfaces, or performance optimization.
allowed-tools: Read, Glob, Grep, Bash

Go Best Practices

Style and best practices guide for Go applications. Contains 60+ rules across 10 categories, synthesized from authoritative sources.

Core skill for: [[Dev]] (implementing Go code) and [[Architect]] (designing Go architectures).

Linting (MANDATORY)

Always run golangci-lint before completing any Go work:

bash
# Run linter on all packages
golangci-lint run ./...

# Run with auto-fix for safe fixes
golangci-lint run --fix ./...

The project uses .golangci.yml which enables:

  • Default linters: errcheck, gosimple, govet, ineffassign, staticcheck, unused
  • Bug detection: bodyclose, nilerr, rowserrcheck, sqlclosecheck, noctx
  • Security: gosec
  • Style: gofumpt, revive, misspell, whitespace
  • Performance: prealloc

For reviews: Run linter first. Any issues found should be tracked as tasks using bd create.

Core Principles

  1. Clarity over cleverness - Code is read more than written
  2. Simplicity - The best code is no code; the second best is simple code
  3. Consistency - Follow established patterns in the codebase
  4. Explicit over implicit - Make dependencies and behavior obvious

When to Apply

Reference these guidelines when:

  • Writing new Go packages or functions
  • Implementing error handling
  • Working with concurrency (goroutines, channels)
  • Designing interfaces
  • Writing tests
  • Reviewing Go code for style issues
  • Refactoring existing Go code

Auto-Detection

This skill auto-activates when working with:

  • Files matching *.go, *_test.go
  • Imports from standard library or common Go packages
  • Patterns like func, type, interface, go func, chan, select
  • Error handling patterns like if err != nil

Rule Categories by Priority

PriorityCategoryImpactPrefix
1Error HandlingCRITICALerr-
2Naming & StyleHIGHname-
3InterfacesHIGHiface-
4ConcurrencyHIGHconc-
5Package DesignMEDIUM-HIGHpkg-
6Functions & MethodsMEDIUMfunc-
7TestingMEDIUMtest-
8PerformanceMEDIUMperf-
9DocumentationLOW-MEDIUMdoc-
10Project StructureLOWstruct-

Quick Reference

1. Error Handling (CRITICAL)

  • err-handle - Always handle errors, never use _
  • err-wrap - Wrap errors with context using fmt.Errorf("...: %w", err)
  • err-types - Use sentinel errors or custom types for expected errors
  • err-strings - Error strings: lowercase, no punctuation
  • err-flow - Indent error handling, keep happy path unindented
  • err-panic - Don't panic for normal errors, only unrecoverable situations
  • err-inband - Avoid in-band errors; use multiple returns

2. Naming & Style (HIGH)

  • name-mixedcaps - Use MixedCaps, not underscores
  • name-initialisms - Keep initialisms uppercase: URL, HTTP, ID
  • name-short - Short names for short scopes (i, r, ctx)
  • name-receivers - Receiver names: 1-2 letters, consistent across methods
  • name-getters - No Get prefix for getters (Name() not GetName())
  • name-packages - Package names: short, lowercase, singular
  • name-avoid - Avoid util, common, misc, base package names

3. Interfaces (HIGH)

  • iface-consumer - Define interfaces where used, not where implemented
  • iface-small - Prefer small interfaces (1-3 methods)
  • iface-accept - Accept interfaces, return concrete types
  • iface-verify - Verify interface compliance at compile time
  • iface-no-mock - Don't define interfaces just for mocking

4. Concurrency (HIGH)

  • conc-goroutine-lifetime - Document when/whether goroutines exit
  • conc-channel-ownership - Establish clear channel ownership
  • conc-prefer-sync - Prefer synchronous functions over async
  • conc-mutex-embed - Embed mutex, don't expose it
  • conc-context-first - Context as first parameter
  • conc-no-context-struct - Don't store context in structs

5. Package Design (MEDIUM-HIGH)

  • pkg-single-purpose - One package, one purpose
  • pkg-internal - Use internal/ for private packages
  • pkg-avoid-init - Avoid init() when possible
  • pkg-import-blank - Side-effect imports only in main
  • pkg-circular - Avoid circular dependencies

6. Functions & Methods (MEDIUM)

  • func-receiver-type - Use pointer receiver for mutations, large structs
  • func-named-returns - Use named returns only for documentation
  • func-naked-returns - Avoid naked returns except in tiny functions
  • func-options - Use functional options for complex configuration
  • func-pass-values - Don't pass pointers to small immutable types

7. Testing (MEDIUM)

  • test-table-driven - Use table-driven tests
  • test-useful-failures - Test failures should say: got X, want Y
  • test-examples - Write testable Example functions
  • test-parallel - Use t.Parallel() for independent tests
  • test-helpers - Use t.Helper() in test helper functions
  • test-subtests - Use t.Run() for subtests

8. Performance (MEDIUM)

  • perf-preallocate - Preallocate slices when size is known
  • perf-strings-builder - Use strings.Builder for concatenation
  • perf-sync-pool - Use sync.Pool for frequently allocated objects
  • perf-avoid-reflect - Avoid reflection in hot paths
  • perf-benchmark - Benchmark before optimizing

9. Documentation (LOW-MEDIUM)

  • doc-package - Every package needs a package comment
  • doc-exported - Document all exported names
  • doc-sentences - Comments are full sentences, start with name
  • doc-examples - Include runnable examples in docs

10. Project Structure (LOW)

  • struct-cmd - Main packages in cmd/
  • struct-internal - Private code in internal/
  • struct-file-size - Keep files under 400 lines when practical
  • struct-pkg-flat - Prefer flat package structure over deep nesting

How to Use

Quick lookup: Reference the rule name from the Quick Reference above, then read the detailed rule:

code
rules/{rule-name}.md

Example: For err-wrap, read rules/err-wrap.md

Each rule file contains:

  • Brief explanation of why it matters
  • Incorrect code example with explanation
  • Correct code example with explanation
  • References to official documentation

Full document: For the complete guide with all rules expanded: AGENTS.md

Integration with Orchestrators

Implementation (auto-dev)

When implementing Go tasks:

  1. Check applicable rules before writing code
  2. Apply CRITICAL rules (err-*) by default
  3. Reference specific rules when reviewing implementations

Architect (Archie)

When designing Go architectures:

  1. Use pkg-* and iface-* rules for package design
  2. Reference struct-* rules for project layout
  3. Include rule citations in ADRs

Key Sources