是什么
引入断言把代码内部依赖的前提条件与不变量显式写成断言:断言是团队对调用契约与实现假设的记录,能让违反点在发生处立即暴露,而不是把错误状态带到更远的地方。它与对外部输入的校验是两件事——外部输入必须始终校验并做错误处理,断言只用于描述代码内部认为不可能出现的情况。
作用与区别
| 作用 | 把前提与不变量显式化,违反时快速失败 |
|---|---|
| 对内 | 对内部假设使用断言,表达不允许出现的情况 |
| 对外 | 对外部输入使用校验与错误处理,不能只靠断言 |
| 运行开关 | 部分语言的断言默认关闭,需要显式启用 |
典型使用场景
- 循环不变量:明确指出循环过程中始终保持成立的条件,便于后续修改时自查
- 参数前提:内部函数约定参数取值区间,违反说明调用方有缺陷
- 状态迁移:方法调用前必须处于某个状态,断言可以在开发阶段立即发现误用
- 算法中间结果:对关键的中间计算做断言,帮助定位逻辑走偏的位置
- 重构保护:拆分复杂逻辑时用断言固定原有假设,避免拆分过程改变行为
示例
示例
# Java:断言表达式与提示信息
assert discount >= 0 && discount <= 1 : "discount out of range";
# Python:断言条件与消息
assert total >= 0, "total must be non-negative"
# 注意:断言只用于内部假设;外部输入必须先做校验断言与校验对照
| 场景 | 手段 | 失败时的处理 |
|---|---|---|
| 用户输入格式错误 | 参数校验 | 返回明确错误信息 |
| 外部接口返回异常结构 | 校验并容错 | 记录日志并按策略降级 |
| 内部函数假设参数非空 | 断言 | 开发与测试阶段立即失败 |
| 状态机迁移前置条件 | 断言或状态检查 | 开发阶段暴露误用;生产可转为显式异常 |
| 业务规则约束 | 校验并返回错误 | 属于正常业务分支,不能只写断言 |
不要把断言当生产校验手段:部分语言与运行时默认关闭断言,代码一旦在关闭状态下运行,所有检查都被静默跳过。对外部输入必须使用校验与错误处理。
断言的表达式不应包含副作用:断言被关闭时,表达式根本不会求值,副作用会随之消失,这类缺陷在开发环境完全看不出来。
落地检查清单
- 断言表达式无副作用,关闭时行为不受影响
- 内部假设用断言,外部输入用校验
- 断言消息说明期望条件,便于快速定位
- 运行环境是否正确开启断言有明确说明