软件开发中的断言(Assert)
断言是一段调试用代码:用来检查某个条件必须为真;如果条件不成立,程序直接抛出错误/终止运行,提醒开发者这里出现了不符合预期的情况。
一句话:断言用来验证“我认为这里一定成立”的假设。
基础语法示例(不同语言)
C / C++
#include <assert.h>
int a = 10;
assert(a > 0); // 断言:a必须大于0。如果a<=0,程序直接崩溃,打印出错位置
Python
a = 10
assert a > 0, "a不能小于等于0"
# 条件为假时抛出 AssertionError,附带提示文本
Java
int a = 10;
assert a > 0 : "a不能小于等于0";
// Java 默认关闭断言,需要 JVM 参数开启:-ea
核心特点
- 只用于开发、测试阶段,不是业务异常处理
很多编译环境(C/C++)在Release发布版本下,断言会被直接编译删掉,代码不执行。
⚠️ 不能用断言校验用户输入!上线后断言失效,校验逻辑就没了。 - 失败后果:程序中断
断言失败代表:程序逻辑已经出现bug,不是正常业务错误。
意思是:代码走到这里,理论上绝对不应该出现这个情况,一旦出现就是程序有漏洞。 - 目的:尽早发现bug
在离bug源头最近的地方直接报错,而不是让错误继续往下跑,最后出现莫名其妙的结果。
✅ 适合用断言的场景
- 函数内部校验:函数内部变量必须满足的前提(内部假设,不是外部输入)
- 不变量检查:循环前后、对象状态必须满足的条件
- 注释替代:用断言代替文字注释,把“假设”变成可执行检查>
例:
assert list != null;我认为这个列表在这里一定不为null(代码内部保证)
❌ 绝对不适合断言的场景
- 校验外部输入(用户请求、接口参数、文件内容)
外部输入异常属于正常业务异常,要用if判断+抛出业务异常,不能用断言。 - 断言表达式里面写有副作用的代码```
坏例子!release下断言被移除,函数不会执行
如果`func()`会修改变量,发布后这行直接消失,逻辑就变了。
## 断言 vs 普通异常(重点区分)
| 断言 Assert | 业务异常 Exception |
| --- | --- |
| 开发者的逻辑假设,**程序bug才会触发** | 业务上可预期的错误,外部因素导致 |
| Release版本可关闭/移除 | 上线后仍然生效,必须处理 |
| 失败直接崩溃,用于调试定位bug | 可以捕获、友好返回提示给用户 |
## 举个通俗例子
写一个除法函数,内部约定:调用方不能传除数0(是代码内部约定,不是用户输入)
assert func() > 0
如果`func()`会修改变量,发布后这行直接消失,逻辑就变了。
## 断言 vs 普通异常(重点区分)
| 断言 Assert | 业务异常 Exception |
| --- | --- |
| 开发者的逻辑假设,**程序bug才会触发** | 业务上可预期的错误,外部因素导致 |
| Release版本可关闭/移除 | 上线后仍然生效,必须处理 |
| 失败直接崩溃,用于调试定位bug | 可以捕获、友好返回提示给用户 |
## 举个通俗例子
写一个除法函数,内部约定:调用方不能传除数0(是代码内部约定,不是用户输入)
def div(a, b):
assert b != 0, "除数不能为0" # 断言:开发者调用时不能传0,传了就是调用代码bug
return a / b
```
如果是用户前端传过来的除数,就要用
if b ==0: raise ValueError,不能用断言。
如果你需要,我可以给你一段带注释的完整Demo,或者讲讲单元测试里断言(JUnit/Pytest assert)和代码里运行时断言的区别。