Go 标准库最佳实践清单
错误处理
- 函数返回
error而不是(bool, error) - 用
fmt.Errorf("...: %w", err)包装底层错误 - 用
errors.Is判断哨兵错误,errors.As提取类型错误 - 哨兵错误以
Err开头命名(ErrNotFound) - 错误消息小写开头,不以标点结尾
- 不吞没错误(
_ = doSomething())
并发
- “不要通过共享内存来通信,而应该通过通信来共享内存”
- 首选 channel 做 goroutine 间通信,Mutex 做共享状态保护
-
defer mu.Unlock()紧跟mu.Lock() - Context 作为函数第一个参数
-
WithCancel/WithTimeout/WithDeadline后defer cancel() - 发送方关闭 channel
- 使用
go test -race检测竞态条件 - 确保每个 goroutine 都能退出
测试
- 测试辅助函数第一行
t.Helper() - 用
t.Run+ 表驱动测试 - 用
t.TempDir()代替手动临时文件 - 用
t.Setenv()代替os.Setenv - 用
t.Cleanup()注册清理函数 - 为公开函数写示例测试 (
ExampleXxx) - 核心路径覆盖率 > 80%
I/O
- 优先使用
io.ReadAll、io.Copy、io.ReadFull而非手写循环 - 接收
io.Reader/io.Writer而非具体类型 - 用完
io.Closer后defer Close() -
bufio.Writer使用后Flush() - 用
bufio.Scanner做行读取 - 用
io.LimitReader防止 OOM - 用
fs.FS接口提高代码可测试性
路径
- 用
filepath.Join拼接路径,不手写分隔符 - 用
filepath.WalkDir遍历目录树 - 处理用户路径前用
filepath.Clean
JSON
- 大整数 ID 用
json:"field,string"或json.Number - 动态类型用
json.RawMessage延迟解析 - 流式处理大文件用
json.Decoder/json.Encoder - 自定义格式实现
MarshalJSON/UnmarshalJSON
性能
- 热路径避免
fmt.Sprintf,用strconv+strings.Builder -
strings.Builder.Grow()预分配容量 - 正则表达式全局预编译 (
regexp.MustCompile) - 频繁创建的对象用
sync.Pool - 复用
http.Client(并发安全) -
sync.Mutex粒度尽可能小 - 反射仅用于框架/库代码,业务代码避免
安全
- pprof 端点不暴露到公网
- TLS 最低版本
VersionTLS12 -
InsecureSkipVerify: true仅用于开发 - 不拼接用户输入到命令中
- 敏感文件权限
0600
其他
- Go 1.19+ 用
atomic.Int64代替atomic.AddInt64 - Go 1.21+ 用
slog代替log - Go 1.16+ 用
os.ReadFile/os.WriteFile - Go 1.22+ for 循环变量不再需要
tt := tt - 用
embed嵌入静态文件 - 用
context.WithTimeout做所有外部调用