谈论 Writing Better Go:10 次 Code Reviews 的经验教训
发布: (2026年1月9日 GMT+8 16:37)
6 min read
原文: Dev.to
Source: Dev.to
处理错误
- 不要悄悄忽略 error(例如使用
_接收 error) - 不要认为这个 error “可以接受”,例如
if err != nil { return nil } - 遇到 error 时立即检查并处理,例如记录日志后认为该 error 已经处理完毕,不再向上层传递
- 不要重复报错 — 如果已经记录了日志再
return,让调用方再次记录日志会导致日志重复
示例(坏的 vs. 好的)
// Bad
if err != nil {
slog.Error(err)
return err
}
// Good
if err != nil {
slog.Error(err)
return nil // 或者在这里处理 error 并且不再向上层返回
}
减轻调用方的负担
return result, nil– 返回结果且没有 error,调用方易于理解return nil, err– 有 error 需要处理,且没有结果return nil, nil– 很糟糕,因为调用方必须自行判断到底是结果还是 error,应该避免return result, err– 也不佳,因为调用方必须同时检查两个返回值才能确定是否可用
使用 Interface
- 不要一开始就创建 interface(很多情况下是从 Java 等语言迁移过来的)或仅仅为了在测试中 mock
- 使用 accept interfaces, return concrete types – 通过 interface 接收,但返回具体类型
- 先使用 concrete type,等到真的需要 interface 时再引入
- Litmus Test:如果不使用 interface 也能测试通过,就不必创建
- 不要仅为了让测试通过而创建 interface – 尽量编写不依赖 interface 的测试
先用 Mutex 再用 Channels
- 使用 channel 会让代码变得复杂,并且容易出现 panic(例如关闭仍在使用的 channel、向已关闭的 channel 发送)或 deadlock
- 先采用简单的方式:使用
sync.Mutex、sync.WaitGroup来管理共享状态 - 只有在 profiling 明显出现瓶颈时才增加 goroutine 或 channel
- 仅在确实需要处理复杂并发逻辑时才使用 channel,而不是用于简单任务
声明(Declare)靠近使用位置
- 在同一文件中,将 constants、variables、functions、types 声明放在实际使用的附近
- 只有在需要被外部 package 使用时才 Export(首字母大写)
- 在函数内部,变量的声明应尽可能靠近使用点
- 将作用域限制得尽可能小,例如在
if语句中只写一条语句
避免 Runtime Panic
- 在使用外部输入前先进行校验
- 如果已经控制了数据流向,就不要再使用
if x == nil,而是信任该处的 error 处理 - 对指针解引用(如
*p = 10)前必须先检查nil - 最安全的做法是 尽量避免使用指针,如果设计上可以做到
排版(Spacing)
- 不要把逻辑层层嵌套(nested
if、for) - 使用 Return Early 与 Flatter Structure:先处理 error,再继续后续工作,或立即剔除不需要继续执行的条件
文件与包的命名
- 避免使用模糊的名称,如
util.go、misc.go、constants.go、interfaces/interfaces.go - 名称应直接说明其职责,而不是所在的结构层级
- 将文件放在与相关代码相近的位置,不要散落在不同目录
声明的分组与顺序
- 按语义分组,而不是按类型分组(例如不要把 controller 分成不同组)
- 按重要性排序声明:
- 对外 API 的函数/结构体(需要让使用者首先看到)
- 为上述代码提供说明或支持的辅助函数
变量命名
- 不要在名称后面加类型后缀(如
userMap、idStr、injectFn)——变量名应描述它保存的内容 - 名称长度应与作用域相匹配:作用域短的变量可以使用短名,全局变量则应使用能够清晰说明意义的名称
文档
- 文档应回答 “为什么” 而不仅是 “做了什么”
- 给出功能或代码存在的原因,以及为何采用当前实现方式
- 注释应传达代码的目的或价值,而不是重复描述实现细节
- Documentation 是意图,而非实现方式 – 帮助阅读者理解设计动机
摘自 Konrad Reiche 的《Writing Better Go: Lessons from 10 Code Reviews》(作者 Asleep‑Actuary‑4428)