Communitygithub.com

mythicalhacker/go-mastery

为AI编码代理提供生产级、地道的Go语言技能——可衡量的Agent技能(支持 Go 1.22–1.26)。在Claude和GPT-5上正确率提升+12–26个百分点,且领域内零回归。

go-mastery 是什么?

该技能为AI编码代理(如Claude Code、Cursor、Codex等)提供了一套全面的Go语言最佳实践体系,覆盖Go 1.22至1.26版本。其核心理念是保持简单、清晰,避免引入其他生态系统的复杂性。通过丰富的参考文件(涵盖并发、HTTP/API、数据库、测试、错误处理、性能、安全、设计模式、分布式系统、云原生、ebpf、事件驱动等30多个专题),代理可以按需深入任何领域。该技能强调:清晰胜过巧妙、组合胜过继承、优先使用标准库、将零值设计为有用、正确处理错误、可控的goroutine、严格遵循代码格式规范(gofmt、go vet、go test -race),以及在满足调用方约定的前提下再优化。项目结构遵循Go惯例(cmd/internal布局),命名规范严格(包名简短小写、导出使用MixedCaps、首字母缩略词全大写),错误处理使用%w包装上下文,并发编程依赖context取消和errgroup模式。该技能已在Claude和GPT-5等主流AI平台上经过验证,在生成Go代码时显著提高了正确率(提升了12-26个百分点),且未引入领域内回归问题。

兼容平台✓Claude Code✓Codex CLI✓Cursor
npx skills add mythicalhacker/go-mastery

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Go Mastery Skill

为任何目的编写生产级、地道的Go代码。本技能编码了Go生态系统截至Go 1.22+(2024-2026年)的集体智慧。

Go 版本基线:1.22 | 涵盖功能至:1.26 | 更新于:2026年2月

在编写任何Go代码之前,请先内化以下原则。如需深入特定主题,请阅读相关引用文件。

引用文件 — 按需阅读

文件何时阅读
references/concurrency.md任何涉及goroutine、channel、sync原语或并行工作的场景
references/http-and-apis.mdHTTP服务器、路由器、中间件、REST/gRPC API、WebSocket
references/database.mdSQL、ORM、连接池、迁移、事务
references/testing.md单元测试、集成测试、基准测试、模糊测试
references/errors-and-resilience.md错误处理、重试、断路器、优雅降级
references/performance.md性能分析、内存分配优化、GC调优、基准测试
references/cli-and-config.mdCLI框架、配置、环境管理
references/project-patterns.md项目布局、依赖注入、插件系统、代码生成
references/platform-and-build.md交叉编译、Windows特定问题、嵌入、分发
references/security.md身份验证、密钥、输入验证、TLS、OWASP模式
references/modern-go.mdGo 1.21–1.26特性、已废弃模式、预训练的常见错误
references/advanced-patterns.md泛型、状态机、流处理、调度、AI/LLM集成
references/advanced-resources.md策划的外部资源:编译器/运行时内部结构、汇编、unsafe、cgo、Raft、K8s操作器、Wasm、密码学、性能分析、书籍、会议、学术论文
references/observability.mdOpenTelemetry配置、追踪、指标、带追踪关联的结构化日志、健康检查、飞行记录器、生产环境检测清单
references/ecosystem-and-tooling.md精选列表(awesome-go)、框架比较(Web、ORM、CLI、DI、Config)、风格指南、CI/CD、Docker、发布管理、漏洞扫描、学习平台、Go治理
references/internals.mdGMP调度器、垃圾回收器、内存模型、栈管理、内存分配器、编译器管道、unsafe、反射、编译器指令
references/networking.mdTCP/UDP服务器、net.Conn超时、连接池、mTLS、Unix套接字、DNS解析器、自定义二进制协议、gnet
references/mcp-and-agents.mdMCP服务器(mcp-go、官方SDK)、工具/资源/提示、代理框架(ADK、langchaingo、eino)、多代理模式、gopls MCP
references/api-design.mdREST命名、分页(游标/偏移)、RFC 9457错误、限流、API版本控制、OpenAPI代码生成(oapi-codegen)、向后兼容性、弃用头部
references/cgo-and-interop.mdCGo基础、C类型映射、跨边界内存管理、指针传递规则、回调、静态/动态链接、交叉编译、纯Go替代方案
references/design-patterns.mdGo中的GoF模式(工厂、构建器、策略、观察者、装饰器)、组合优于继承、决策树
references/distributed-systems.mdRaft、Outbox模式、Saga、分布式锁、幂等性、CRDT、一致性哈希
references/cloud-native.mdKubernetes client-go、controller-runtime操作器、准入Webhook、领导者选举、Helm/Kustomize
references/debugging-and-diagnostics.mdDelve调试器、堆栈跟踪、GODEBUG标志、性能分析工作流程、症状到诊断表
references/style-synthesis.md合并Google + Uber + 社区风格规则、命名、格式化、代码组织
references/modules-and-dependencies.mdgo.mod操作、MVS、工作区、GOPROXY、GOAUTH、vendoring、多模块单仓库
references/encoding-and-serialization.mdJSON(v1/v2)、Protocol Buffers、MessagePack、CBOR、CSV、YAML、TOML、格式决策表
references/wasm-and-embedded.mdWebAssembly(WASI、浏览器)、go:wasmexport、TinyGo、嵌入式/IoT模式
references/migration-guides.md从Python、Java、TypeScript、Rust、C++到地道Go的转换——概念映射和陷阱
references/testing-advanced.md基于属性的测试(rapid)、契约测试(Pact)、负载测试(Vegeta)、混沌工程、synctest高级
references/supply-chain-security.mdgovulncheck、SBOM生成、SLSA框架、cosign、可重现构建、GODEBUG兼容性
references/ebpf.md从Go使用eBPF(cilium/ebpf)、bpf2go工作流程、追踪、网络、内核级性能分析
references/event-driven.mdKafka、RabbitMQ、NATS消费者/生产者、Watermill框架、DLQ、精确一次模式
references/data-structures-and-caching.mdcontainer/heap、container/list、LRU缓存、singleflight、分片映射、布隆过滤器、弱引用缓存、缓存策略模式(旁路/写通/写后)
references/ai-ml-beyond-llm.mdONNX Runtime推理、Gonum、向量数据库客户端、嵌入管道、从Go进行ML服务
references/file-io.md文件操作、io.Reader/Writer组合、缓冲I/O、流式处理、路径处理、os.Root、fs.FS抽象、fsnotify

核心哲学

Go故意设计得简单。抵制从其他生态系统引入复杂性的冲动。

  1. 清晰胜过巧妙。 代码被阅读的次数比编写的次数多10倍。显式胜于隐式——未来的维护者(包括未来的你)会感谢你。
  2. 组合胜过继承。 嵌入接口和结构体;避免深层层次结构。Go没有类,这是有意的——小而可组合的部件胜过复杂的类型树。
  3. 接受接口,返回结构体。 函数应依赖行为(接口)并暴露具体类型。这使调用点保持灵活,同时使实现可发现和可调试。
  4. 让零值有用。 设计类型使得 var x T 无需初始化即可使用。这消除了一整类的空指针错误,并让API感觉自然(bytes.Buffer、sync.Mutex、http.Client 在零值时都可工作)。
  5. 错误是值。 处理它们;永远不要忽略它们。使用 fmt.Errorf("doing X: %w", err) 包装上下文。被丢弃的错误会成为数小时后在生产中显现的静默失败。
  6. 不要启动你无法停止的goroutine。 每个goroutine都需要通过上下文取消或通道关闭来实现关闭路径。泄露的goroutine会无限消耗内存并使优雅关闭不可能。
  7. 标准库优先。 Go的标准库异常完整。仅在标准库确实不足时才使用第三方库——更少的依赖意味着更少的安全审计、更少的版本冲突和更快的构建。
  8. 代码在 gofmt 清理、构建和检查完成之前不算完成。 运行 gofmt/goimports、go build、go vet、go test -race 和 golangci-lint——让它们成为CI门禁;竞态检测器能发现审查中不可见的错误。在无工具访问的情况下发出代码时,手动保持同样的标准:保持gofmt格式,并且只包含你实际使用的导入(未使用的导入是编译错误——这是交换一种惯用法后出现的经典失误)。
  9. 先尊重调用者的约定,再优化。 当任务指定了确切的标识符、签名、输出格式或类型时,精确地复现它们——即使你会有不同的命名或结构。默认选择满足规范的最简单的正确解决方案;仅当任务的复杂性要求时才添加抽象、间接层或防御性层。匹配要求的表面是正确性的一部分——无端的重命名或重构会破坏调用者和测试。

项目结构

从简单开始。仅当项目需要时才添加结构。

单一二进制(CLI或小型服务)

myapp/
├── go.mod
├── main.go              # package main, 入口点
├── app.go               # 核心应用逻辑
├── app_test.go
└── internal/            # 根据需要的私有包
    └── parser/
        ├── parser.go
        └── parser_test.go

多二进制/生产服务

myproject/
├── go.mod
├── cmd/                 # 入口点——薄的main()函数
│   ├── api-server/
│   │   └── main.go
│   └── worker/
│       └── main.go
├── internal/            # 私有应用代码(由编译器强制执行)
│   ├── auth/
│   ├── user/            # 领域包:handler + service + repo
│   │   ├── handler.go
│   │   ├── service.go
│   │   ├── repository.go
│   │   └── model.go
│   ├── platform/        # 横切关注点:db, cache, logging
│   │   ├── postgres/
│   │   └── redis/
│   └── middleware/
├── pkg/                 # 可选:公共可重用库
├── api/                 # OpenAPI规范、protobuf定义
├── migrations/          # SQL迁移文件
├── scripts/             # 构建、部署、开发工具
├── configs/             # 默认配置文件
└── Makefile

关键规则:

  • internal/ 由Go编译器强制执行——此处的代码不能被外部模块导入。
  • cmd/*/main.go 应该很薄:解析标志、连接依赖、调用 run()、处理关闭。
  • 按领域/功能分组,而不是按技术层。避免 models/、controllers/、services/——这是Java式的分层,与Go的包模型相悖。
  • 避免 utils/、helpers/、common/ 包——按包提供的功能命名,因为模糊的名称会吸引不相关的代码并使导入失去意义。
  • 目录即包。不要仅仅为了组织而创建目录。

命名约定

// 包:简短、小写、单单词。不使用下划线或混合大小写。
package user      // 好
package userService // 坏——混合大小写

// 导出:MixedCaps。未导出:mixedCaps。下划线是合法的,但社区将其视为风格缺陷——它们表示非惯用代码。
func ParseRequest()  // 导出
func parseHeader()   // 未导出

// 接口:方法名 + "-er" 后缀用于单方法接口
 type Reader interface { Read(p []byte) (n int, err error) }
type Validator interface { Validate() error }

// Getter:Owner(),而不是GetOwner()。Setter:SetOwner()。
func (u *User) Name() string       // getter——"Get"前缀是非Go的
func (u *User) SetName(n string)   // setter

// 首字母缩略词:全大写。URL、HTTP、ID、API——而不是Url、Http、Id、Api。
type HTTPClient struct{}
var userID int

// 错误变量:ErrXxx。错误类型:XxxError。
var ErrNotFound = errors.New("not found")
type ValidationError struct { Field string; Message string }

// Context:第一个参数,始终命名为ctx。这是通用的Go约定,使得上下文传播在任何代码库中都能立即识别。
func (s *Service) GetUser(ctx context.Context, id string) (*User, error)

错误处理

这是Go最独特的模式。掌握它。

// 检查每个错误——使用%w包装上下文
f, err := os.Open(name)
if err != nil {
    return fmt.Errorf("opening config %s: %w", name, err)
}
defer f.Close()

// errors.AsType——泛型类型化错误提取 [Go 1.26+]
// 优先于errors.As:类型安全,无需预声明变量。
if pathErr, ok := errors.AsType[*fs.PathError](err); ok {
    fmt.Println("failed at path:", pathErr.Path)
}

关键规则:

  • return err 不加上下文会使调试痛苦——始终使用 fmt.Errorf("doing X: %w", err) 包装。
  • 在库代码中使用 log.Fatal(err) 会调用 os.Exit(1),跳过延迟清理——将错误返回给调用者。
  • panic() 用于程序员错误,而不是运行时条件——返回错误给调用者。
  • 使用 %v(而不是 %w)包装第三方错误,以避免将调用者耦合到底层错误类型。
  • 错误消息风格: 小写,无标点:fmt.Errorf("reading config file: %w", err)。

参见 references/errors-and-resilience.md 了解哨兵错误、自定义错误类型、errors.Join、重试模式、断路器和优雅降级。


并发要点

参见 references/concurrency.md 了解包含errgroup、工作池和扇出/扇入的全面模式。核心规则:

  1. 使用context进行取消。 每个goroutine必须检查 ctx.Done()——没有它,就没有办法发出“停止工作”的信号。
  2. 优先使用 errgroup 而不是原始的 sync.WaitGroup。 捆绑了等待 + 错误收集 + 上下文取消。参见 concurrency.md 了解包含 SetLimit 的完整示例。
  3. 保护共享状态——使用通道进行通信,当更简单时使用互斥锁。注释每个互斥锁保护的内容。
  4. 每个goroutine都需要一个关闭路径。 没有取消检查 = 泄露的goroutine = 内存泄漏。
  5. goroutine中的panic会杀死整个进程。 在派生的goroutine中recover,或使用 sourcegraph/conc。

新的同步原语:

sync.OnceValue / sync.OnceValues [Go 1.21+]——类型安全的惰性初始化,取代 sync.Once + 包变量:

var loadConfig = sync.OnceValues(func() ([]byte, error) {
    return os.ReadFile("config.json") // 仅执行一次,从任何goroutine调用都是安全的
})
data, err := loadConfig() // 后续调用返回缓存结果

sync.WaitGroup.Go [Go 1.25+]——结合了 Add(1) + go func + Done():

var wg sync.WaitGroup
wg.Go(func() { process(1) })
wg.Go(func() { process(2) })
wg.Wait()

通道大小: 无缓冲(0)用于同步,缓冲(1)用于信号,缓冲(N)用于有界工作。


接口

// 接受接口,返回具体类型
type UserStore interface {
    GetUser(ctx context.Context, id string) (*User, error)
}
func NewService(store UserStore) *Service { return &Service{store: store} }

// 保持接口小巧——1-3个方法。从小接口组合成大接口。
type ReadWriter interface { Reader; Writer }

// 在消费者一侧定义接口,而不是生产者一侧
// 这样避免了接口导入循环,并保持包解耦。

测试

// 表驱动测试——Go中最常见的测试模式
func TestParse(t *testing.T) {
    tests := []struct {
        name  string
        input string
        want  int
    }{
        {"simple", "42", 42},
        {"negative", "-1", -1},
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got, err := Parse(tt.input)
            if err != nil {
                t.Errorf("Parse() error = %v", err)
                return
            }
            if got != tt.want {
                t.Errorf("Parse() = %v, want %v", got, tt.want)
            }
        })
    }
}

// 使用 `t.Cleanup` 进行资源清理 [Go 1.14+]
func TestWithFile(t *testing.T) {
    f, err := os.CreateTemp("", "test")
    if err != nil {
        t.Fatal(err)
    }
    t.Cleanup(func() { os.Remove(f.Name()) })
    // ... 使用文件 ...
}

关键规则:

  • 始终使用 -race 标志运行测试——竞态检测器是Go最好的调试工具之一。
  • 使用testdata/目录管理测试数据文件。
  • 集成测试使用 //go:build integration 构建标签。
  • 基准测试函数以 BenchmarkXxx(b *testing.B) 命名。
  • 模糊测试函数以 FuzzXxx(f *testing.F) 命名。

包管理

// 推荐模块路径:github.com/user/repo
module github.com/yourorg/yourproject

go 1.22

require (
    github.com/google/uuid v1.6.0
)

关键规则:

  • 使用语义化版本控制进行依赖管理。
  • 定期运行 go mod tidy 保持go.mod和go.sum干净。
  • 对内部包使用工作区(go work)以减少多模块仓库中的重复。
  • 在生产构建中使用vendoring以确保可重现性。

资源链接

相关技能