Go语言用iota定义状态码/错误码的核心目标是类型安全、语义清晰、可读性强、不易误用;需定义专属类型(如StatusCode)、用iota赋值、支持跳过值或偏移编号、实现Stringer接口、按模块分组独立重置iota。

Go 语言中用 iota 定义状态码或错误码,核心目标是:类型安全、语义清晰、可读性强、不易误用。不靠魔法数字,也不靠手动递增,而是让编译器帮你管好序号和类型。
定义带自定义类型的枚举
避免直接用 int,而是先声明专属类型(如 StatusCode 或 ErrorCode),再用 iota 赋值。这样能防止把状态码当普通整数传参或比较。
- 显式写出类型,增强可读性与类型检查:
type StatusCode intconst (StatusOK StatusCode = iota // 0StatusCreated // 1StatusBadRequest // 2) - 所有值都属于
StatusCode类型,StatusOK == 0会编译报错,必须写成StatusOK == StatusOK或显式转换
跳过无效值或偏移起始编号
实际业务中,0 常被用作“未设置”或“非法值”,所以常从 1 开始;或者中间需要留空(比如预留扩展位)。
- 用
_ = iota跳过第 0 项:const (_ = iotaErrInvalidInputErrNotFoundErrTimeout)→ 值分别为 1、2、3 - 用
iota + 1000统一偏移,便于区分模块:const (ErrAuthBase = 1000 + iotaErrInvalidTokenErrExpiredToken)→ 1000、1001、1002
为错误码添加可读字符串(Stringer 接口)
调试、日志、API 返回时,直接打印 ErrInvalidToken 比打印 1001 有用得多。实现 String() 方法即可。
立即学习“go语言免费学习笔记(深入)”;
- 只需在类型上实现
func (e ErrorCode) String() string,fmt.Println(e)就自动显示名称 - 建议用
switch显式映射,不依赖顺序,也方便加注释:func (e ErrorCode) String() string {switch e {case ErrInvalidToken: return "invalid_token"case ErrExpiredToken: return "token_expired"default: return "unknown_error"}}
按模块分组,每个 const 块独立重置 iota
不同功能域的错误码应分开定义,利用 const 块边界天然重置 iota 的特性,避免跨模块污染或意外复用。
- 例如:
const ( // HTTP 状态码StatusOK StatusCode = iotaStatusCreated)const ( // 业务错误码ErrUserNotFound ErrorCode = iotaErrInsufficientBalance) - 两个块互不影响,
ErrUserNotFound是 0,不是延续前面的 2










