Files
OpenFlare/.agents/skills/go-code-review/SKILL.md
T
2026-08-04 11:40:32 +08:00

11 KiB
Raw Blame History

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+)
sources
Go Wiki CodeReviewComments, Uber Style Guide
Bash(bash:*)

Go 代码审查清单

审查流程

使用 assets/review-template.md 格式化代码审查输出,确保结构与"必须修复 / 建议修复 / 吹毛求疵"的严重程度分组保持一致。

  1. 运行 gofmt -d . 和 go vet ./... 先捕获机械性问题
  2. 逐文件阅读 diff;对于每个文件,按以下类别顺序检查
  3. 标记问题时需要包含具体行号引用和规则名称
  4. 审查完所有文件后,重新阅读标记项以确认它们是真实的问题
  5. 按严重程度分组汇总发现(必须修复、建议修复、吹毛求疵)

验证:完成审查后,再次阅读 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