Agent Skills
返回列表
💻

Go 语言习惯用法

开发编程 更新于 2026.08.29

将以下提示词粘贴到你的 AI 对话框中:

请根据 https://skillhub.cn/install/skillhub.md,安装 @user_3c6cb52e/golang-idioms-z8wk

技能介绍

为什么需要这份规范

Go 代码看起来简单,但团队代码里反复出现同类问题:错误被 log.Println 打印后就丢弃,调用方无法用 errors.Is 判断;包里定义了四五个方法的大接口,实际只用到其中一个;go func() 启动后没有任何停止路径,测试结束时 goroutine 泄漏;context.Context 被塞进 struct 里到处传。这些不是编译器能发现的错误,而是团队缺少一份可执行的约定。

这份技能提供什么

@user_3c6cb52e/golang-idioms-z8wk 把常见的 Go 习惯用法整理成规则清单,直接覆盖以下场景:

  • 错误处理:统一用 fmt.Errorf("context: %w", err) 包装并保留错误链;在合适的层级处理错误,不要一边 log 一边 return;预期条件使用哨兵错误。
  • 接口设计:接口在消费方定义,而不是实现方;优先组合小接口,直接复用标准库的 io.Reader、io.Writer、fmt.Stringer;单方法接口按方法名加 -er 命名。
  • 并发模式:goroutine 必须通过 context 取消或关闭 channel 来停止;用 sync.WaitGroup 等待完成;生产与消费速度不匹配时使用带缓冲的 channel;worker pool 与 fan-out/fan-in 作为参考模式。
  • context 传递:所有 I/O 函数把 context.Context 作为第一个参数;外部调用设置 context.WithTimeout 或 WithDeadline;创建后立即 defer cancel();context.WithValue 只用于 trace ID 这类请求级数据,不要存进 struct。
  • 测试与模块管理:表驱动测试配合 t.Helper() 与 t.Cleanup();测试数据放入 testdata/ 目录;每次提交前执行 go mod tidy,锁定主版本并查看 changelog 后再升级。
  • 零值设计:优先让 struct 的零值可以直接使用,而不是到处写构造函数;修改接收者用指针接收者,只读用值接收者;不应由用户直接设置的字段不要导出。
  • 结构化日志:Go 1.21+ 直接使用标准库 log/slog,日志字段结构化,不做字符串拼接,每条日志带请求 ID、用户 ID 和操作名。
  • 反模式清单:返回 interface{} 代替具体类型、用 init() 做复杂初始化、用 _ 忽略错误不加注释、共享状态优先用 mutex 而不是 channel、长函数里裸返回等。

适用边界

这套规则是通用工程约定,不替代具体业务的判断:context.WithValue 的使用需要克制,全局替换成 mutex 前要先确认锁竞争情况,表驱动测试也不是所有场景都更易读。规则会随 Go 版本演进,例如 log/slog 要求 Go 1.21+,升级依赖时应重新对照 changelog,而不是机械套用。

使用场景

  • 审查团队 Go 服务的代码,统一错误包装与 context 传递写法,让 errors.Is 能正常工作
  • 编写并发任务时设计 worker pool,并确保 goroutine 能通过 context 取消而不泄漏
  • 重构接口定义,把大接口拆成小接口,并把接口声明移到消费方一侧
  • 为 Go 1.21+ 项目接入 log/slog 结构化日志,替换字符串拼接并补齐请求 ID 字段

适合人员

  • Go 服务端工程师:想让团队的错误处理和 context 传递风格保持一致
  • 从 Java 或 Python 转 Go 的开发者:需要快速掌握 goroutine 与 channel 的惯用法
  • 负责代码评审的技术负责人:希望有一份可对照的反模式清单来指出问题
  • 维护开源 Go 库的作者:想让接口设计和测试写法符合社区预期