用途:这是一份 Go 语言惯用写法(idioms)参考,用于指导编写符合社区惯例的 Go 代码,覆盖错误处理、接口设计、并发、测试、模块管理等主题。
主要能力与要点: 错误处理:库代码返回错误而非 panic;用 fmt.Errorf("context: %w", err) 包装并保留上下文,配合 errors.Is/errors.As;为预期情况定义哨兵错误(如 ErrNotFound);在合适层级处理错误,不要既记录日志又返回同一错误。 接口设计:接口保持小(1-3 个方法),在使用方(消费端)定义;接受接口、返回结构体;优先复用 io.Reader、io.Writer、fmt.Stringer;单方法接口以方法名加 er 后缀命名。 并发与通道:给出 Worker Pool 与 Fan-out/Fan-in 模式;context.Context 作为第一个参数;确保 goroutine 可被停止;用 sync.WaitGroup 等待完成;生产消费速度不同时用带缓冲通道;不要启动无法确定如何停止的 goroutine。 上下文传播:I/O 函数首参传 context;外部调用用 WithTimeout/WithDeadline;创建可取消 context 后 defer cancel();WithValue 仅用于请求级值;不要把 context 存入结构体。 测试:表驱动测试与 t.Run 子测试;测试辅助函数用 t.Helper();用 t.Cleanup() 清理资源;测试夹具放 testdata/ 目录。 模块管理:给出 go.mod 结构及命令 go mod tidy、go mod verify、go list -m -u all、go get -u ./...、go mod vendor;建议每次提交前运行 go mod tidy,锁定主版本,更新前查看变更日志。 零值设计:让类型零值可用(如 sync.Mutex、bytes.Buffer);优先使用零值有意义的结构体而非构造函数;修改接收者用指针接收者,只读用值接收者。 结构化日志:使用标准库 log/slog(Go 1.21+),输出结构化字段而非字符串拼接,每条日志包含请求 ID、用户 ID 与操作名。 常见反模式:返回 interface{}/any 而非具体类型;用 init() 做复杂初始化;用 _ 忽略错误且无注释;goroutine 无生命周期管理;锁范围过大导致争用;通道误用(简单共享状态优先用互斥锁);长函数中使用裸返回。
使用方式与限制:资料以代码示例与规则清单形式呈现,未提供安装命令、独立工具或运行方式,也未说明收费、平台与效果。具体项目中的取舍需结合实际情况判断。