mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-28 05:46:36 +08:00
11 KiB
11 KiB
name, description, license, compatibility, metadata, allowed-tools
| name | description | license | compatibility | metadata | allowed-tools | ||
|---|---|---|---|---|---|---|---|
| go-code-review | Use when reviewing Go code or checking code against community style standards. Also use proactively before submitting a Go PR or when reviewing any Go code changes, even if the user doesn't explicitly request a style review. Does not cover language-specific syntax — delegates to specialized skills. | Apache-2.0 | Web server example in references uses slog (Go 1.21+) |
|
Bash(bash:*) |
Go 代码审查清单
审查流程
使用
assets/review-template.md格式化代码审查输出,确保结构与"必须修复 / 建议修复 / 吹毛求疵"的严重程度分组保持一致。
- 运行
gofmt -d .和go vet ./...先捕获机械性问题 - 逐文件阅读 diff;对于每个文件,按以下类别顺序检查
- 标记问题时需要包含具体行号引用和规则名称
- 审查完所有文件后,重新阅读标记项以确认它们是真实的问题
- 按严重程度分组汇总发现(必须修复、建议修复、吹毛求疵)
验证:完成审查后,再次阅读 diff 以验证每个标记的问题都是真实的。删除任何无法用具体行号引用的发现。
格式化
- 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 bool 的多返回值 → 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 - 接收器名称:类型的一两个字母缩写(
c代表Client);不使用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:作为第一个参数;不放在 struct 中;不自定义 Context 类型;即使认为不需要也应传递 → go-context
接口
- 接口位置:在消费方包中定义,而非实现方;生产者返回具体类型 → go-interfaces
- 不提前定义接口:不在使用前定义;不在实现方"为了 mock"而定义 → go-interfaces
- 接收器类型:如果会修改状态、有 sync 字段或体积大,使用指针;小的不可变类型使用值;不要混用 → go-interfaces
数据结构
- 空切片:优先使用
var t []string(nil)而非t := []string{}(非 nil 零长度) → go-data-structures - 复制:小心复制含指针/切片字段的结构体;不按值复制
*T方法的接收器 → go-data-structures
安全性
- 加密随机数:密钥使用
crypto/rand,不使用math/rand→ go-defensive - 不 panic:常规错误处理使用 error 返回;仅在真正特殊的情况下 panic → go-defensive
声明与初始化
- 分组相似的:相关的
var/const/type放在括号块中;不相关的分开 → go-declarations - var vs :=:有意使用零值时用
var;显式赋值时用:=→ go-declarations - 缩小作用域:将声明移到使用位置附近;使用 if-init 限制变量作用域 → go-declarations
- Struct 初始化:始终使用字段名;省略零值字段;零值 struct 使用
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
- 日志中无敏感信息:PII、凭证和令牌永远不记录在日志中 → 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:仅当所有测试都需要带清理的公共设置时使用;优先使用作用域化的 helper → go-testing
- 真实传输:优先使用
httptest.NewServer+ 真实客户端而非 mock HTTP → go-testing
自动化检查
运行自动化预审查检查:
bash scripts/pre-review.sh ./... # 文本输出
bash scripts/pre-review.sh --json ./... # 结构化 JSON 输出
或手动:gofmt -l <path> && go vet ./... && golangci-lint run ./...
在进入上述清单之前修复所有问题。有关 linter 设置和配置,请参阅 go-linting。
综合示例
在构建生产级 HTTP 服务器并希望验证代码是否正确应用了并发、错误处理、context、文档和命名规范时,阅读 references/WEB-SERVER.md。
相关 Skill
- 风格基础:在解决格式化争议或应用"清晰 > 简单 > 简洁"优先级时,请参阅 go-style-core
- Linting 设置:在配置 golangci-lint 或将自动化检查添加到 CI 时,请参阅 go-linting
- 错误策略:在审查错误包装、哨兵错误或 handle-once 模式时,请参阅 go-error-handling
- 命名规范:在评估标识符名称、接收器名称或包-符号重复时,请参阅 go-naming
- 测试模式:在审查表驱动结构、失败消息或 helper 使用的测试代码时,请参阅 go-testing
- 并发安全:在审查 goroutine 生命周期、channel 使用或互斥锁放置时,请参阅 go-concurrency
- 日志实践:在审查日志使用、结构化日志或 slog 配置时,请参阅 go-logging