14.1尝试 与 捕获
用 尝试 包裹可能出错的代码,用 捕获 异常类型 作为 e 拦截异常并访问异常对象:
cql
# 尝试 与 捕获
尝试:
打印(10 / 0)
捕获 异常 作为 e:
打印("出错了:", e)捕获 异常 会捕获所有异常;也可以一次写多个 捕获 分支处理不同类型的错误(对应 Python 的多分支 except)。
14.2捕获 具体异常
CQL 内置了常见异常的中文名,例如 值错误、类型错误、键错误、索引错误、除零错误、运行时错误 等:
cql
# 捕获具体异常
尝试:
值 = 整数("不是数字")
捕获 值错误 作为 e:
打印("值错误:", e)14.3否则 与 最终
否则 块只在没有异常时执行(对应 Python 的 try-else);最终 块无论是否发生异常都会执行(对应 finally):
cql
# 否则 与 最终
尝试:
打印(10 / 2)
否则:
打印("没有异常,执行否则块")
最终:
打印("无论是否异常都会执行")out
5.0
没有异常,执行否则块
无论是否异常都会执行14.4抛出
用 抛出 异常类型("消息") 主动抛出异常,中断当前执行并向上层传递:
cql
# 抛出
函数 检查(分数):
如果 分数 < 60:
抛出 值错误("不及格:" + 文本(分数))
返回 "通过"
尝试:
检查(45)
捕获 值错误 作为 e:
打印("捕获到:", e)14.5自定义异常
继承 异常 类即可定义自己的异常,用 跳过 保持类体为空:
cql
# 自定义异常
类 余额不足错误 继承 异常:
跳过
尝试:
抛出 余额不足错误("余额不足")
捕获 余额不足错误 作为 e:
打印("业务异常:", e)14.6异常链
用 抛出 ... 从 e 在捕获异常后抛出新的异常,并保留原始异常作为原因(对应 Python 的 raise ... from e):
cql
# 异常链
尝试:
尝试:
1 / 0
捕获 除零错误 作为 e:
抛出 运行时错误("计算失败") 从 e
捕获 运行时错误 作为 e:
打印("外层捕获:", e)
打印("原因:", e.__cause__)下面是 examples/exception.cql 的银行账户取款完整示例,它综合运用了自定义异常、抛出、否则与最终:
cql
# CQL 示例:银行账户取款
类 余额不足错误 继承 异常:
跳过
类 银行账户:
函数 __init__(自身, 初始余额):
自身.余额 = 初始余额
函数 取款(自身, 金额):
如果 金额 > 自身.余额:
抛出 余额不足错误("余额不足:需要 {},仅有 {}".format(金额, 自身.余额))
自身.余额 -= 金额
返回 自身.余额
账户 = 银行账户(100)
尝试:
账户.取款(150)
捕获 余额不足错误 作为 e:
打印("捕获到异常:", e)
否则:
打印("取款成功")
最终:
打印("当前余额:", 账户.余额)out
捕获到异常: 余额不足:需要 150,仅有 100
当前余额: 100