mcpField
G
go-code-review

go-code-review

github.com/existential-birds测试与质量85201 次安装12 周前更新
代码仓库

关于 go-code-review

go-code-review 是面向 Go 项目的代码审查技能,依据项目 Go 版本、改动上下文和适用清单组织审查,并要求在报告问题前完成核验。

主要功能

  1. 01核对 Go 版本基线
  2. 02审阅完整函数上下文
  3. 03按范围选择审查清单
  4. 04错误处理与并发指引
  5. 05按严重性校准问题

适用场景

  1. 01审查改动的 Go 函数
  2. 02检查错误处理与资源清理
  3. 03结合 Go 版本评估并发改动

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/existential-birds/beagle --skill go-code-review

安装后在 Claude Code 中输入/go-code-review确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
common-mistakes.md
concurrency.md
error-handling.md
interfaces.md

详细介绍

Go 代码审查

审查工作流

按以下顺序执行。在满足以下所有 通过 条件之前,不要报告问题。

  1. 确定基准 go.mod——打开 go.mod 并读取 go 指令。
    **通过:**能够准确说出 go X.YY 的值(在审查前言或工作笔记中)。仅在与此基准版本匹配时应用版本限定的建议(循环变量捕获适用于 1.22 之前的版本,slog/结构化日志从 1.21 开始,errors.Join 从 1.20 开始)。

  2. 阅读周边代码——对于每个已更改的 .go 文件,阅读包含改动的完整函数或逻辑单元,而不只是差异片段。
    **通过:**每个已更改文件中,至少阅读了一个包含改动的完整外层函数(或包级 init/var 块)。

  3. 确定检查清单范围——判断适用审查检查清单中的哪些部分(错误处理、并发、接口/类型、资源、命名)。加载这些部分的参考资料;与差异无关的部分可跳过。
    **通过:**审查(或工作笔记)列出了应用的检查清单部分,或将不适用的部分标记为 N/A,并给出与差异相关的一句话理由(例如“改动不涉及并发”)。

  4. 报告前核验——加载并遵循 review-verification-protocol。
    通过:对于将要报告的每个问题,均满足协议中的报告前核验清单(已阅读实际代码、检查周边上下文、区分“错误”与“风格不同”等)。

硬性门槛(相同步骤,表述更简洁)

步骤客观通过条件
1在给出版本限定的建议之前,已记录 go.mod 中的 go X.YY。
2已阅读每个已更改文件的完整外层上下文,而不只是差异。
3已列出适用的检查清单部分,或根据差异给出理由并标记为 N/A;按需打开参考资料。
4对每个报告的问题,均已完成 review-verification-protocol。

输出格式

按以下格式报告问题:

[FILE:LINE] ISSUE_TITLE
Severity: Critical | Major | Minor | Informational
Description of the issue and why it matters.

快速参考

问题类型参考资料
未检查错误、未包装错误、errors.Joinreferences/error-handling.md
竞态条件、通道误用、goroutine 生命周期references/concurrency.md
接口污染、命名、泛型references/interfaces.md
资源泄漏、defer 误用、slog、命名references/common-mistakes.md

审查检查清单

错误处理
  • 已检查所有错误(没有未经注释说明的 _ = err)
  • 已为错误添加上下文包装(fmt.Errorf("...: %w", err))
  • 使用 errors.Is/errors.As,而非字符串匹配
  • 使用 errors.Join 聚合多个错误(Go 1.20+)
  • 发生错误时同时返回零值
并发
  • 没有 goroutine 泄漏(存在上下文取消或关闭信号)
  • 仅由发送方关闭通道,且恰好关闭一次
  • 使用互斥锁或 sync 类型保护共享状态
  • 使用 WaitGroup 等待 goroutine 完成
  • 沿调用链传递上下文
  • 已处理循环变量捕获(仅适用于 Go 1.22 之前的代码库)
接口和类型
  • 接口由使用方定义,而非生产方
  • 接口名称遵循 -er 约定
  • 接口保持精简(1–3 个方法)
  • 构造函数返回具体类型
  • 优先使用 any 而非 interface{}(Go 1.18+)
  • 在适当情况下使用泛型,而非 any 或代码生成
资源和生命周期
  • 资源创建后立即使用 defer 关闭
  • 始终关闭 HTTP 响应体
  • 不在循环中使用未经闭包封装的 defer
  • 避免使用 init() 函数,改用显式初始化
命名与风格
  • 导出的名称有文档注释
  • 没有重复名称(user.UserService → user.Service)
  • 超过 5 行的函数中没有裸返回
  • 将上下文作为第一个参数传递
  • 结构化日志使用 slog,而非 log(Go 1.21+)

严重性校准

严重(阻止合并)
  • 对 I/O、网络或数据库操作的错误未进行检查
  • Goroutine 泄漏(没有关闭路径)
  • 共享状态上的竞态条件(并发访问 map 时未同步)
  • 资源无界累积(在循环中使用 defer、连接未关闭)
主要(应修复)
  • 返回的错误缺少上下文(直接 return err)
  • 启动的 goroutine 缺少 WaitGroup
  • 对可恢复的错误使用 panic
  • 上下文未传递给下游调用
次要(考虑修复)
  • Go 1.18+ 代码库中使用 interface{} 而非 any
  • 导出的名称缺少文档注释
  • 名称重复
  • 已知大小的切片未预分配
信息性(仅作提示)
  • 建议在已有代码生成的地方添加泛型
  • 接口设计的重构思路
  • 未经测量验证效果的性能优化

何时加载参考资料

  • 审查错误返回模式 → error-handling.md
  • 审查 goroutine、通道或 sync 类型 → concurrency.md
  • 审查类型定义、接口或泛型 → interfaces.md
  • 常规审查(资源、命名、init、性能)→ common-mistakes.md

有效模式(不要标记)

以下都是可接受的 Go 模式——报告这些问题会浪费开发者的时间:

  • 带原因注释的 _ = err — 有解释地有意忽略错误
  • 空接口 / any — 用于真正的泛型代码,或与无类型 API 互操作
  • 短函数中的裸返回 — 在少于 5 行且使用命名返回值的函数中可以接受
  • 不关闭的通道 — 当消费者通过取消上下文而非关闭通道来停止时
  • 用于保护结构体字段的互斥锁 — 即使只能通过方法访问,这也是正确的封装方式
  • 带原因的 //nolint 指令 — 附有说明时可以接受
  • 循环中的 Defer — 有意在函数作用域进行清理时(例如,分批处理文件)
  • 函数选项模式 — type Option func(*T) 搭配 With* 构造函数是惯用写法
  • 用于热点路径的 sync.Pool — 在对性能要求较高的代码中,可用于减少分配压力
  • main/测试中的 context.Background() — 可作为顶层调用的有效根上下文
  • 带 default 的 select — 非阻塞通道操作,是有意采用的模式
  • 小作用域中的短变量名 — i、err、ctx、ok 是惯用的 Go 写法

依赖上下文的规则

仅在符合特定条件时标记以下问题:

问题仅当以下条件成立时才标记
未检查错误错误返回可采取行动(可以重试、记录日志或向上传递)
Goroutine 泄漏该 goroutine 没有上下文取消路径
缺少 defer资源在下一次获取或返回前未显式关闭
接口污染接口有 > 1 个方法,且只有一个使用方
循环变量捕获go.mod 指定的 Go 版本 < 1.22
缺少 sloggo.mod 指定的 Go 版本 >= 1.21,且代码使用 log 包输出结构化日志

提交问题前

满足 Review Workflow 中的 第 4 步:加载 review-verification-protocol,并针对每个问题完成报告前检查。

评论

支持 Markdown