mcpField
G
go-idiomatic

go-idiomatic

github.com/o-marsters-1997开发0100 次安装今天更新
代码仓库

关于 go-idiomatic

Go Idiomatic 为开发者编写或审查代码提供该仓库特有的 Go 约定,并按主题指向详细参考资料和相关 skill。

主要功能

  1. 01错误处理与日志规则
  2. 02代码组织约定
  3. 03函数与命名指引
  4. 04按主题指向参考资料
  5. 05Go 工具要求

适用场景

  1. 01实施 Go 仓库代码变更
  2. 02审查 Go 代码约定
  3. 03查找特定 Go 主题的参考资料

安装

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

$npx skills add https://github.com/o-marsters-1997/my-claude-code --skill go-idiomatic

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

包含的文件

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

evals/
evals.json
evals/files/optional-field/
go.mod
evals/files/optional-field/internal/user/
user.go
evals/files/refactor-store/
go.mod
evals/files/refactor-store/helpers/
helpers.go
evals/files/refactor-store/store/
store.go
evals/files/server-settings/
go.mod
evals/files/server-settings/cmd/app/
main.go
evals/files/server-settings/internal/server/
server.go
references/
concurrency.md
database.md
errors.md
exec.md
http-client.md
logging.md
middleware.md
optional.md
patterns.md
secrets.md
value-vs-pointer.md

详细介绍

Go 惯用实践

本仓库中 Go 的规则,适用于与通用 Go 实践不同或对其进一步明确的情况。以下规则适用于每项变更;详细说明和示例见参考文档。

查阅位置

继续阅读前,先找到相应的参考文档:

如果你正在处理……加载此文档
Goroutine、通道、同步原语、errgroup、泄漏、竞态references/concurrency.md
添加 sentinel 或错误类型、在包之间或转换为 HTTP 响应时转换错误、记录错误来源、在 defer 中清理、panicreferences/errors.md
HTTP 中间件:请求 Content-Type、CSRF、会话 Cookie 属性references/middleware.md
存储会话或重置令牌、重置或更改密码、加密列references/secrets.md
为 main 或组件提供日志记录器、选择日志级别、区分 CLI 输出与日志references/logging.md
接口设计、零值、标识符类型、类型化值集合、反模式references/patterns.md
编写或审查测试、基准测试、模糊测试、测试数据库go-testing 技能
可选字段或返回值——何时使用 Option[T]references/optional.md
指针接收者与值接收者、变更与可选性references/value-vs-pointer.md
为第三方 API 搭建 Go HTTP 客户端、编写 NewXxxClient,或为出站 HTTP 调用附加身份验证references/http-client.md
使用 os/exec 调用 git、gh 或其他 CLI、解析其 --json 输出、在测试中伪造其行为references/exec.md
在 SQL 中存储数据:存储包边界、事务、NULL、约束错误、连接池设置references/database.md
为 htmx 渲染 html/template:页面与片段的区分、重定向、HX-* 标头、.tmpl 文件htmx-go-templates 技能

错误与日志记录

几乎每项变更都会返回或报告错误,因此这些规则适用于所有 Go 工作,而不只是错误处理相关任务:

  1. 使用 fmt.Errorf("<verb> <noun>: %w", err) 包装错误。错误字符串使用小写,不加标点,也不写 "failed to"。
  2. 每个错误只处理一次:附带上下文后返回,或在调用链顶层记录日志。切勿两者兼做。
  3. 仅当其他包中的调用方会据此分支处理时,才导出 sentinel。在检测到该条件的位置定义它,并在包边界将依赖项的错误转换为自己的错误。
  4. 切勿使用 _ = 丢弃错误。将清理错误合并到返回的错误中;若没有可返回的对象,则在 Warn 级别记录。
  5. 仅因程序员错误才使用 panic:对常量输入使用 Must 辅助函数,或处理不可能出现的情况。
  6. 只有错误会在此处停止传播的组件(处理程序、工作进程、长期运行的服务)才应通过构造函数字段注入 *slog.Logger。下层代码应返回错误且不接收日志记录器。main 创建唯一的日志记录器;任何代码都不调用 log.*、slog.Info 或 slog.Default()。
  7. 日志消息必须是常量;可变数据放入 snake_case 键值属性,错误使用 err。切勿记录秘密或个人数据。
  8. 用户要求的输出应写入注入的 io.Writer,而不是日志记录器。

常规的 return fmt.Errorf(...) 或日志语句只需遵守这些规则。添加 sentinel 或错误类型、将错误转换为 HTTP 响应、包装驱动程序或出站调用错误,或处理清理错误时,加载 references/errors.md;接入日志记录器、选择日志级别或区分 CLI 输出时,加载 references/logging.md。


测试

编写、编辑或审查 _test.go 文件时:加载 go-testing skill,它负责规定 Go 测试的编写方式,包括测试数据库。测试什么(测试类型、每种测试的价值、可复用模式)由仓库提供的 testing-policy 规定。


代码组织

  1. 应用将 main 放在 cmd/<app>/main.go 中,该文件只负责连接依赖;其他所有内容都放在 internal/ 下。pkg/ 用于供仓库外导入的库模块;在应用中使用它,意味着提供了一个实际并不存在的公共 API。
  2. 在含义不同的多个包中,第 三 次重复时再提取共享逻辑,而不是第二次。与某个领域紧密耦合的辅助函数应放在 internal/ 中,靠近其主要调用方。
  3. 包名应体现其用途(stringx、idgen、timeutil)。只有当 utils 被多个包使用且不导入 internal/ 中的内容时,才允许使用。绝不允许使用 helpers 和 common:总能找到一个更准确的名称。
  4. 不要使用包级状态,例如在 init() 中设置全局 *sql.DB。通过构造函数传递依赖。
  5. main 只解析一次环境变量,将其放入有类型的配置结构体中,并进行验证;遇到无效值时,应在启动时退出,而不是等到第一个需要该值的请求到来时才退出。构造函数只接收自身使用的字段,而非整个结构体。cmd/ 以下的代码不得调用 os.Getenv。

函数设计

  1. 参数超过 3–4 个时,将它们归入结构体,或对将来可能扩展的构造函数使用函数选项(opts ...Option);新增选项向后兼容,新增位置参数则不兼容。

  2. 复杂参数应先声明为具名局部变量,再传入调用,而不是将构造函数调用嵌套在内联表达式中:

    sentAt := time.Now().Add(-24 * time.Hour)
    priority := Priority(3)
    client.Send(NewMessage(sender, recipient, sentAt, priority))
    
  3. 优先进行守卫检查并提前返回;正常路径应保持在底部,不缩进,且 return 后不要接 else。使用 switch,而不是 if/else if 链。

  4. 可变更的对象和可测量的大型结构体使用指针;小型不可变类型使用值。绝不要用 *T 表示“可能未设置”;这种情况应使用 Option[T]。


命名与注释

函数名应体现其返回值或操作(ParseConfig、IsExpired),布尔值名称应体现谓词(canRetry)。只使用 Go 惯例缩写(ctx、err、id、r、w)。

~/.claude/rules/comments.md 规定哪些内容值得写注释。它是权威规范,本 skill 不会重复或弱化其中的要求。编辑文件前先阅读该文件,并按其原文要求执行,包括行数上限和仅为导出标识符编写文档注释的规则。internal/ 并非公共 API。审查 Go 代码的注释质量时,使用 clean-comments skill。不要要求它匹配文件现有的注释密度。


工具

完成前运行 gofmt、goimports、go vet ./... 和 golangci-lint run。机械规则交由 linter 处理,不要在此重复。对于现有违规,绝不要添加 //nolint:应修复问题,或暂时关闭相关规则,直到问题修复。


另请参阅

Skill适用场景
go-testing测试编写方式:断言、替身、表格驱动测试、测试数据库
tddTDD 周期、红绿重构、先编写测试
clean-comments审查并移除 Go 代码中的解释性注释
improve-codebase-architecture识别结构性改进和浅层模块
simplify实现后审查变更代码的质量、复用性和效率

评论

支持 Markdown