Go 代码审查
目标:变更应使代码库更健康。不要求完美。 不要因个人偏好而阻止变更。
步骤 1:获取变更
- 如果用户提供了 diff、PR 或文件,直接使用。
- 在 Git 仓库中:
git diff --stat main...HEAD,然后git diff main...HEAD(如果main不存在,尝试master或origin/main)。 对于未提交的工作:git diff和git diff --staged。 - 如果变更目的不明确,用一句话询问。
步骤 2:阅读上下文
- 打开每个被修改函数周围的整个文件,而不仅仅是 diff 行。
- 查找被修改导出函数的调用者:
grep -rn "FuncName(" --include=*.go - 在
go.mod中检查 Go 版本。某些建议依赖于版本(自 Go 1.22 起循环变量为每次迭代新变量)。
步骤 3:运行工具(如果可以运行命令)
go build ./...
go vet ./...
go test -race ./... # 如果仓库慢,只测试更改的包
golangci-lint run ./... # 仅当已安装或仓库有配置文件时
报告真正的失败。对于格式化问题,只说一次“运行 gofmt”;不要列出每一行。 如果无法运行命令,用一句话说明。
步骤 4:按以下顺序审查
先看大问题。如果设计有问题,先说设计,跳过小问题。
- 设计 – 此变更是否属于此处(此包、此服务)?是否与系统其他部分匹配?现在是否是合适的时机?
- 功能 – 它是否实现了作者想要的功能?这对使用者(最终用户和未来的开发者)是否有益?考虑边界情况和并发。
- 复杂度 – 读者能否快速理解?注意过度工程:为想象的未来而非当前问题编写的代码。
- 测试 – 同一变更中是否有测试?如果代码出错,测试是否会失败?测试是否简单?
- 命名 – 清晰,不太长,符合 Go 风格。
- 注释 – 解释为什么,而不是是什么。移除过时的注释和已完成的 TODO。
- 风格 – gofmt,风格指南。个人偏好 = 仅小问题。
- 一致性 – 风格指南优于周围代码。如果指南未规定,遵循周围代码。
- 文档 – 如果行为改变,更新 README、godoc、配置/环境变量、迁移。
- 每一行 – 阅读所有人工编写的代码。生成的代码(
*.pb.go、mocks、sqlc 输出)可以略读。 - 代码健康 – 整个系统因此变更变得更好还是更坏?
- 好的方面 – 明确指出你看到的真正好的地方。
对于每个领域的 Go 特定检查,阅读 references/go-checklist.md。
始终检查其中的错误、并发和资源部分;大多数 Go 错误都在那里。
严重性标签
- 阻塞器 – 错误、数据竞争、goroutine 泄漏、安全问题、损坏的测试、错误的设计。合并前必须修复。
- 应修复 – 真正的问题,但不紧急。作者可以争论。
- 小问题 – 小的可选改进。始终以“小问题:”开头评论。
- 疑问 – 你不理解的地方。如果你不理解,别人也不会;要求更清晰的代码。
不要编造问题。好的变更获得简短的审查。 如果你不确定某个问题是否是错误,使用疑问,而不是阻塞器。 如果要求只审查某些文件或方面,说明你审查了哪些部分。
输出格式
## 摘要
1-2 句话:变更的作用。结论:批准 / 带评论批准 / 需要修改。
## 阻塞器
- `path/file.go:42` – 问题是什么以及为什么重要。
```go
// 建议修复
```
## 应修复
## 小问题
## 疑问
## 好的方面
## 我检查了什么
运行的工具及其结果,审查的文件,跳过的内容。
省略空章节。每条评论:问题、原因、修复。保持简短。