4、错误码常量定义:使用iota定义错误码、错误码分组、错误码命名规范
在Go语言中,错误码常量的定义是领域边界断言的第一道防线。使用iota枚举器可以保证错误码的连续性与可维护性,同时通过分组与命名规范,让错误码具备自描述能力,降低跨模块的认知成本。
4.1 使用iota定义基础错误码
iota是Go预定义的标识符,在const块中每出现一次即自增1。利用这一特性,可以高效定义一组递增的错误码常量:
package errcode
type ErrCode int
const (
ErrSuccess ErrCode = iota // 0
ErrUnknown // 1
ErrInvalidParam // 2
ErrNotFound // 3
ErrTimeout // 4
ErrPermissionDenied // 5
)
关键点:使用
iota定义错误码时,第一个常量必须显式赋值为iota(或0),后续常量自动递增。建议始终从0开始,将ErrSuccess作为零值,符合Go零值语义。
4.2 错误码分组:按领域边界划分
单一线性枚举无法满足复杂系统的领域划分需求。通过iota配合位移或分组常量,可以实现按模块/领域分组的错误码体系:
package errcode
const (
// 通用错误码组:0-99
ErrSuccess ErrCode = iota // 0
ErrUnknown // 1
ErrInvalidParam // 2
ErrNotFound // 3
ErrTimeout // 4
ErrPermissionDenied // 5
// 用户领域错误码组:100-199
ErrUserNotFound ErrCode = iota + 100 // 100
ErrUserAlreadyExists // 101
ErrUserPasswordIncorrect // 102
ErrUserAccountLocked // 103
// 订单领域错误码组:200-299
ErrOrderNotFound ErrCode = iota + 200 // 200
ErrOrderAlreadyPaid // 201
ErrOrderExpired // 202
ErrOrderStatusInvalid // 203
)
分组策略:每个领域分配100个码位(0-99、100-199、200-299…),既保证组间隔离,又为未来扩展预留空间。实际项目中可根据领域复杂度调整组大小(如50或200)。
4.3 错误码命名规范
错误码命名直接影响代码可读性与领域语义的传达。推荐以下规范:
| 规范维度 | 规则 | 示例 | 反例 |
|---|---|---|---|
| 前缀 | 统一使用Err前缀 |
ErrInvalidParam |
InvalidParam |
| 领域标识 | 错误码名包含领域名词 | ErrUserNotFound |
ErrNotFound(歧义) |
| 动词时态 | 使用过去分词或形容词 | ErrOrderAlreadyPaid |
ErrOrderPay(歧义) |
| 否定形式 | 避免双重否定 | ErrPermissionDenied |
ErrNotAllowed(模糊) |
| 长度 | 不超过5个单词 | ErrUserAccountLocked |
ErrUserAccountHasBeenLockedByAdmin |
4.4 错误码分组与领域边界关系图
下图展示了错误码分组如何映射到领域边界,以及iota在分组中的自增机制:
4.5 进阶:使用iota+位移实现位域错误码
对于需要组合多个错误状态的场景(如权限校验),可以使用iota配合位移操作定义位域错误码:
package errcode
type PermissionBits uint32
const (
PermRead PermissionBits = 1 << iota // 1
PermWrite // 2
PermExecute // 4
PermDelete // 8
PermAdmin // 16
)
// 组合使用
const PermReadWrite = PermRead | PermWrite // 3
注意:位域错误码适用于需要按位组合的场景(如权限、状态标记),不适用于普通业务错误码。普通业务错误码应保持互斥性,避免组合歧义。
4.6 错误码常量定义最佳实践清单
- 始终从0开始:将
ErrSuccess作为零值,符合Go零值语义,避免未初始化错误码产生歧义。 - 按领域分组:每个领域分配独立的码位区间,区间大小根据领域复杂度预留(建议50-200)。
- 命名自描述:错误码名称应能直接反映错误原因和所属领域,避免通用名称。
- 使用
Err前缀:统一前缀便于IDE自动补全和代码搜索。 - 避免魔法数字:所有错误码必须通过常量定义,禁止在业务代码中直接使用数字。
- 文档化:在常量定义处添加注释,说明每个错误码的触发条件和处理建议。
领域边界断言:错误码分组本质上是领域边界的数值化表达。当跨领域调用返回错误码时,接收方可以通过错误码区间快速判断错误来源,无需深入理解对方领域的内部逻辑。这正是“错误码断言”的核心价值——在数值层面实现领域隔离。