关于 go-code-review
面向 Go 开发者的代码审查技能,提供结构化检查清单。它结合自动化预审与 Go 专项指南,并按严重程度整理审查结果。
主要功能
- 01运行 gofmt、go vet 和 golangci-lint 预检
- 02检查 Go 风格、错误、并发与安全
- 03按规则名和代码行标注问题
- 04按严重程度组织审查结果
适用场景
- 01合并前审查 Go 代码变更
- 02检查 HTTP 服务代码中的并发与关闭问题
- 03统一整理必须修复、建议修复和细微问题
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ cxuu/ golang-skills --skill go-code-review安装后在 Claude Code 中输入/go-code-review确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/review-template.mdreferences/WEB-SERVER.mdscripts/pre-review.sh详细介绍
Go 代码审查清单
兼容性:
references/WEB-SERVER.md中的log/slog示例需要 Go 1.21+。
资源路由
assets/review-template.md- 格式化审查结果时使用,包含 Must Fix、Should Fix 和 Nits 部分。scripts/pre-review.sh- 手动审查前运行,以收集 gofmt、go vet 和 golangci-lint 的结果。references/WEB-SERVER.md- 审查结合了并发、上下文、日志记录、错误处理和关闭行为的 HTTP 服务时阅读。
审查流程
格式化代码审查结果时使用
assets/review-template.md,以确保结构一致,并按 Must Fix / Should Fix / Nits 严重程度分组。
- 先运行
gofmt -d .和go vet ./...,找出机械性问题 - 逐个文件阅读差异;对每个文件,按以下顺序检查各类别
- 标出问题的具体行号和规则名称
- 审查完所有文件后,重新检查已标出的问题,确认它们确实存在
- 按严重程度(必须修复、应该修复、小问题)汇总发现
验证:完成审查后,再次阅读差异,确认每个标出的问题都确实存在。删除任何无法用具体行号证明的问题。
格式
- gofmt:代码已使用
gofmt或goimports格式化 → go-linting
文档
- 注释句子:注释为完整句子,以所描述对象的名称开头,并以句号结尾 → go-documentation
- 文档注释:所有导出名称都有文档注释;非简单的未导出声明也有文档注释 → go-documentation
- 包注释:包注释紧邻 package 子句,中间没有空行 → go-documentation
- 命名结果参数:仅在能明确含义时使用(例如,有多个相同类型的返回值),不要仅为启用裸返回而使用 → go-documentation
错误处理
- 处理错误:不要用
_丢弃错误;应处理、返回错误,或(特殊情况下)触发 panic → go-error-handling - 错误字符串:使用小写字母,不带标点(以专有名词或缩写开头时除外)→ go-error-handling
- 带内错误:不要使用魔法值(-1、""、nil);应通过多返回值中的 error 或 ok 布尔值表示 → go-error-handling
- 错误流程缩进:优先处理错误并返回;尽量减少正常流程的缩进 → go-error-handling
命名
- MixedCaps:使用
MixedCaps或mixedCaps,不要使用下划线;未导出名称使用maxLength,而不是MAX_LENGTH→ go-naming - 首字母缩写:大小写保持一致:
URL/url、ID/id、HTTP/http(例如ServeHTTP、xmlHTTPRequest)→ go-naming - 变量名:作用域有限时使用短名称(
i、r、c);作用域更广时使用较长名称 → go-naming - 接收者名称:使用类型名称的一或两个字母缩写(
Client使用c);不要使用this、self、me;各方法中保持一致 → go-naming - 包名:避免名称重复(使用
chubby.File,而不是chubby.ChubbyFile);避免使用util、common、misc→ go-packages - 避免使用内置名称:不要遮蔽
error、string、len、cap、append、copy、new、make→ go-declarations
并发
- Goroutine 生命周期:明确 goroutine 是否以及何时退出;如果不明显,请记录 → go-concurrency
- 同步函数:优先使用同步函数而非异步函数;如有需要,让调用方添加并发 → go-concurrency
- 上下文:作为第一个参数;不放在结构体中;不使用自定义 Context 类型;即使认为不需要,也要传递 → go-context
接口
- 接口位置:在消费者包中定义,而非实现方;生产方返回具体类型 → go-interfaces
- 不要过早定义接口:在实际使用前不要定义;不要在实现方一侧为了“模拟”而定义 → go-interfaces
- 接收者类型:如果会修改数据、包含同步字段或体积较大,则使用指针;小型不可变类型使用值;不要混用 → go-interfaces
数据结构
- 空切片:优先使用
var t []string(nil),而非t := []string{}(非 nil 的零长度切片)→ go-data-structures - 复制:复制带有指针/切片字段的结构体时要谨慎;不要按值复制
*T方法的接收者 → go-data-structures
安全
- 密码学随机数:密钥使用
crypto/rand,不要使用math/rand→ go-defensive - 不要 panic:正常错误处理应使用错误返回值;仅在真正异常的情况下使用 panic → go-defensive
声明和初始化
- 分组相似项:相关的
var/const/type放在带括号的代码块中;不相关的项分开 → go-declarations - var 与 :=:有意使用零值时用
var;显式赋值时用:=→ go-declarations - 缩小作用域:将声明移至靠近使用的位置;使用 if-init 限制变量作用域 → go-declarations
- 结构体初始化:始终使用字段名;省略零值字段;零值结构体使用
var→ go-declarations - 使用
any:新代码中优先使用any,而非interface{}→ go-declarations
函数
- 文件顺序:类型 → 构造函数 → 导出方法 → 未导出方法 → 工具函数 → go-functions
- 签名格式:换行时,所有参数各占一行,并在末尾加逗号 → go-functions
- 未命名参数:对于含义不明确的 bool/int 参数,添加
/* name */注释,或使用自定义类型 → go-functions - Printf 命名:接受格式字符串的函数名称以
f结尾,以便通过go vet检查 → go-functions
风格
- 行长:没有严格限制,但应避免过长的行;按语义换行,而非按任意长度换行 → go-style-core
- 裸返回:仅用于短函数;中型/大型函数使用显式返回 → go-style-core
- 传递值:不要仅为了节省字节而使用指针;对于小型固定大小类型,传递
string而非*string→ go-performance - 字符串拼接:简单拼接使用
+;格式化使用fmt.Sprintf;循环中使用strings.Builder→ go-performance
日志记录
- 使用 slog:新代码使用
log/slog,而非log或fmt.Println进行运行日志记录 → go-logging - 结构化字段:日志消息使用静态字符串和键值属性,而非 fmt.Sprintf → go-logging
- 使用适当的级别:Debug 用于开发者跟踪,Info 用于值得关注的事件,Warn 用于可恢复的问题,Error 用于失败 → go-logging
- 日志中不记录机密信息:绝不记录个人身份信息、凭据和令牌 → go-logging
导入
- 导入分组:先导入标准库,然后空一行,再导入外部包 → go-packages
- 导入重命名:除非名称冲突,否则避免重命名;发生冲突时重命名本地/项目专用导入 → go-packages
- 空白导入:
import _ "pkg"仅用于 main 包或测试 → go-packages - 点导入:仅用于测试中的循环依赖变通方案 → go-packages
泛型
- 适用场景:仅当多种类型共享相同逻辑且接口无法满足需求时使用 → go-generics
- 类型别名:新类型使用类型定义;别名仅用于包迁移 → go-generics
测试
- 示例:包含可运行的
Example函数或演示用法的测试 → go-documentation - 有用的测试失败信息:消息应包含错误原因、输入、实际值和期望值;顺序为
got != want→ go-testing - TestMain:仅在所有测试都需要共同的设置和清理时使用;优先考虑作用域限定的辅助函数 → go-testing
- 真实传输:优先使用
httptest.NewServer和真实客户端,而非模拟 HTTP → go-testing
自动化检查
运行自动化的审查前检查:
bash scripts/pre-review.sh ./... # text output
bash scripts/pre-review.sh --json ./... # structured JSON output
或者手动运行:gofmt -l <path> && go vet ./... && golangci-lint run ./...
继续执行上述清单前,请先修复所有问题。有关 linter 的设置和配置,请参阅 go-linting。
相关技能
- 风格基础:在解决格式争议或应用清晰度 > 简洁性 > 精炼性的优先级时,请参阅 go-style-core
- Linting 设置:在配置 golangci-lint 或向 CI 添加自动化检查时,请参阅 go-linting
- 错误处理策略:在审查错误包装、哨兵错误或仅处理一次模式时,请参阅 go-error-handling
- 命名约定:在评估标识符名称、接收者名称或包符号重复时,请参阅 go-naming
- 测试模式:在审查测试代码中的表驱动结构、失败信息或辅助函数用法时,请参阅 go-testing
- 并发安全:在审查 goroutine 生命周期、通道用法或互斥锁位置时,请参阅 go-concurrency
- 日志实践:在审查日志用法、结构化日志或 slog 配置时,请参阅 go-logging
评论
支持 Markdown