SuperAPI AI 工具集

golang

编程与开发

查看项目

更新于 10-15 15:31

技能介绍

本技能是一个 Go 语言开发最佳实践集合,来源为 saisudhir14/claude-skills 下的 golang 技能。根据资料描述,它适用于编写、审查或重构 Go 代码的场景,提供面向生产环境的 Go 最佳实践,涵盖错误处理、并发、命名、测试等内容,并标注已针对 Go 1.25 更新。

用途与组织方式 该技能由多个子技能和一个参考资料目录组成:skills/go-error-handling、skills/go-concurrency、skills/go-testing、skills/go-performance、skills/go-code-review、skills/go-linting、skills/go-project-layout、skills/go-security,深入讲解位于 references/。核心理念是可读代码应按以下顺序优先考虑这些属性:清晰(目的与理由对读者明显)、简单(以最简单的方式达成目标)、简洁(高信噪比)、可维护(易于正确修改)、一致(与周边代码库风格一致)。

错误处理 要求返回错误,生产代码中不要 panic;当调用方需要 errors.Is/errors.As 时用 %w 包装,在边界处用 %v;上下文信息保持简短,如 "new store: %w",而非 "failed to create new store: %w";只处理一次错误,不要既记录日志又返回同一错误;错误字符串小写、无标点;先处理错误、保持快乐路径缩进最小;多独立失败用 errors.Join(Go 1.20+);哨兵错误变量用 Err 前缀,类型用 Error 后缀。示例:if err != nil { return fmt.Errorf("load config: %w", err) }。

并发 通道大小用 0(无缓冲)或 1,其他大小需要理由;记录 goroutine 生命周期(何时与如何退出);有错误返回的 goroutine 用 errgroup.Group 而非手动 sync.WaitGroup;优先同步函数,让调用方自行加并发;零值互斥锁不要用指针,也不要嵌入公开结构体;使用类型化原子(Go 1.19+):atomic.Int64、atomic.Bool、atomic.Pointer[T];sync.Map(Go 1.24+)在键集合不相交时性能显著提升。示例使用 errgroup.WithContext 与 SetLimit(10)。

命名与接收者 始终使用 MixedCaps,不用下划线(MaxLength 而非 MAX_LENGTH);首字母缩略词大小写一致(URL、ID、HTTP);变量长度由作用域决定(循环用 i,全局用 DefaultTimeout);接收者名为 1-2 个字母缩写,方法间保持一致,不用 this/self;包名小写单词,避免 util/common/misc;避免重复(http.Serve 而非 http.HTTPServe)。指针接收者用于修改接收者、较大结构体、包含 sync.Mutex、需与其他方法一致;值接收者用于小且不可变结构体、不修改状态、map/func/chan、基础类型。

导入与模块管理 导入分三组:标准库、外部、内部,以空行分隔;仅在避免冲突时重命名;除测试文件处理循环依赖外不用点导入;空白导入(import _ "pkg")仅用于 main 或测试。Go 1.24+ 可用 tool 指令在 go.mod 中跟踪工具依赖,并提供 go get -tool、go tool、go get tool、go install tool 等命令用法。

结构体、切片与映射 结构体初始化始终使用字段名(位置式会在变更时出问题);省略零值字段;不要在公开结构体中嵌入类型;零值结构体用 var。切片优先 nil 切片(仅 JSON 需要 [] 时用 []string{});边界处复制以防被修改;已知大小时预分配;使用 slices 与 maps 包。

泛型与迭代器 不同类型写相同代码时用泛型,使用 cmp.Ordered 或自定义约束;Go 1.24+ 支持泛型类型别名(type Set[T comparable] = map[T]struct{});不要过度泛化。Go 1.23+ 支持通过函数实现自定义迭代器,示例给出 Backward;Go 1.24+ 提供 strings.Lines、strings.SplitSeq、strings.SplitAfterSeq 等字符串/字节迭代器。

结构化日志与性能 使用 slog.Info、slog.With、slog.NewJSONHandler 等;Go 1.24+ 用 slog.DiscardHandler 在测试中抑制日志;键名保持一致,用 slog.Group 分组。性能方面:用 strconv 而非 fmt(strconv.Itoa(n) 而非 fmt.Sprintf("%d", n));避免重复 []byte 转换;预分配 map 容量;拼接用带 Grow() 的 strings.Builder。

测试、资源管理与常见陷阱 测试采用表驱动并用 t.Parallel() 运行子测试;用 go-cmp 而非 reflect.DeepEqual;失败信息包含输入、got、want;初始化失败用 t.Fatal;接口属于消费者而非生产者;Go 1.24+ 有 T.Context、T.Chdir、b.Loop();Go 1.25+ 有 synctest.Test 可用合成时间做确定性并发测试。资源管理(Go 1.24+)包括 runtime.AddCleanup、weak.Pointer[T]、os.Root。常见陷阱表列出循环变量捕获(Go 1.22+ 已修复)、defer 立即求值参数、nil 接口与 nil 指针、未检查错误先用结果、map 迭代顺序、切片 append 共享底层数组等,并给出对应修复方式。

Lint、项目布局与安全 使用 golangci-lint 作为标准聚合器,推荐 errcheck、govet、staticcheck、revive、gosimple、goimports、errorlint、bodyclose;可通过 go get -tool 添加为工具依赖,CI 中可用 golangci/golangci-lint-action;尽量修复而非 //nolint。项目布局:cmd/ 每个可执行文件一个子目录、保持 main.go 精简;internal/ 为私有包;避免 pkg/、src/、models/、utils/;小项目扁平即可;Dockerfile 采用多阶段构建、CGO_ENABLED=0、distroless 基础镜像。安全方面:参数化 SQL 查询、os.Root 限定文件访问、边界处校验、不要硬编码或记录密钥、仅用标准加密、设置 HTTP 超时、govulncheck 扫描依赖、CI 中始终运行 go test -race。

实验性内容与文档 Go 1.25 实验特性 encoding/json/v2 可通过 GOEXPERIMENT=jsonv2 启用。文档要求注释为以声明名开头的完整句子,包注释写在 package 声明之前且不留空行。资料还列出了参考来源:Google Go Style Guide、Uber Go Style Guide、Effective Go、Go Code Review Comments 及 Go 1.23/1.24/1.25 发布说明。