panic
konghuang(恐慌 / panic)立即终止整个程序,用在程序已经无法继续运行的地方:
cpro
hs get_age(x z64) z64 {
ruguo (x < 0) {
konghuang("年龄不能为负")
}
fanhui x
}cpro
函数 get_age(x i64) i64 {
如果 (x < 0) {
恐慌("年龄不能为负")
}
返回 x
}cpro
fn get_age(x i64) i64 {
if (x < 0) {
panic("年龄不能为负")
}
return x
}- 参数必须是一个字符串,可以是拼接出来的:
konghuang("未知的模式: " +[zifuchuan] mode) - 只能单独写成一条语句,不能放进表达式里:
cpro
bl s = konghuang("boom") // ✗
dayin(konghuang("boom")) // ✗cpro
变量 s = 恐慌("boom") // ✗
打印(恐慌("boom")) // ✗cpro
var s = panic("boom") // ✗
print(panic("boom")) // ✗输出
程序终止时,向标准错误输出一行,包含文件、行号、列号和消息:
/path/to/main.cp:7:9: panic: 年龄不能为负不会做任何清理
panic 后程序立即结束:
- nocopy 结构体 的清理方法不会执行
- 打开的文件不会被关闭,还没写入磁盘的数据会丢失
内存和文件句柄由操作系统回收。所以重要数据不要依赖 panic 路径,该显式关闭的要显式关闭。
panic 还是 kecuo
cpro 有两套错误机制,区别很明确:
kecuo + changshi / buhuo | konghuang | |
|---|---|---|
| 用于 | 可以预料、调用方有办法应对的失败 | 不该发生、发生了说明程序有 bug |
| 例子 | 文件不存在、字符串不是数字、网络超时 | 数组越界、走到了不可能到达的分支 |
| 调用方 | 可以捕获、重试、提示用户 | 无法捕获,程序直接结束 |
判断方法:问自己"调用方拿到这个错误能做什么"。能重试、能换个做法、能提示用户,就用 kecuo;什么也做不了、这就是个 bug,就用 konghuang。
写给别人用的函数,尽量用 kecuo,把决定权交给调用方。
语言内建的 panic
下面这些运行时错误也会 panic,输出格式相同:
| 场景 | 触发条件 |
|---|---|
| 数组下标越界 | a[i] 的 i 不在 [0, 长度) 内 |
| 切片越界 | a[start..end] 的端点不合法 |
| 空数组弹出 | 对空数组调用 tanchu() |
| 字符串越界 | qu、zichuan 的位置超出范围 |
能在编译时确定越界的常量下标,会直接报编译错误。
不支持
- 捕获 panic 并恢复执行(
recover):暂不支持 - panic 时打印调用栈:暂不支持
