错误处理
异常
#你的 Dart 代码可以抛出和捕获异常。异常是表示发生意外情况的错误。如果异常没有被捕获,则引发异常的 隔离区 将被挂起,并且通常隔离区及其程序将被终止。
与 Java 相反,Dart 的所有异常都是未检查异常。方法不声明它们可能抛出的异常,并且您不需要捕获任何异常。
Dart 提供了 Exception
和 Error
类型,以及许多预定义的子类型。当然,你也可以定义你自己的异常。但是,Dart 程序可以抛出任何非空对象——不仅仅是 Exception 和 Error 对象——作为异常。
抛出
#这是一个抛出或 引发 异常的示例:
throw FormatException('至少需要 1 个部分');
你也可以抛出任意对象:
throw '羊驼用完了!';
因为抛出异常是一个表达式,所以你可以在 => 语句中抛出异常,以及在允许表达式的任何其他地方:
void distanceTo(Point other) => throw UnimplementedError();
捕获
#捕获异常会阻止异常传播(除非你重新抛出异常)。捕获异常使你有机会处理它:
try {
breedMoreLlamas();
} on OutOfLlamasException {
buyMoreLlamas();
}
要处理可能抛出多种类型的异常的代码,你可以指定多个 catch 子句。第一个与抛出的对象的类型匹配的 catch 子句将处理该异常。如果 catch 子句没有指定类型,则该子句可以处理任何类型的抛出对象:
try {
breedMoreLlamas();
} on OutOfLlamasException {
// 一个具体的异常
buyMoreLlamas();
} on Exception catch (e) {
// 其他任何异常
print('未知异常:$e');
} catch (e) {
// 没有指定类型,处理所有异常
print('一个真正未知的东西:$e');
}
如前面的代码所示,你可以使用 on
或 catch
或两者都使用。如果需要指定异常类型,则使用 on
。如果你的异常处理程序需要异常对象,则使用 catch
。
你可以为 catch()
指定一个或两个参数。第一个是被抛出的异常,第二个是堆栈跟踪(一个 StackTrace
对象)。
try {
// ···
} on Exception catch (e) {
print('异常详情:\n $e');
} catch (e, s) {
print('异常详情:\n $e');
print('堆栈跟踪:\n $s');
}
要部分处理异常,同时允许它传播,请使用 rethrow
关键字。
void misbehave() {
try {
dynamic foo = true;
print(foo++); // 运行时错误
} catch (e) {
print('misbehave() 部分处理了 ${e.runtimeType}。');
rethrow; // 允许调用者看到异常。
}
}
void main() {
try {
misbehave();
} catch (e) {
print('main() 完成了 ${e.runtimeType} 的处理。');
}
}
finally
#要确保某些代码无论是否抛出异常都会运行,请使用 finally
子句。如果没有 catch
子句与异常匹配,则在 finally
子句运行后传播异常:
try {
breedMoreLlamas();
} finally {
// 始终清理,即使抛出异常。
cleanLlamaStalls();
}
finally
子句在任何匹配的 catch
子句之后运行:
try {
breedMoreLlamas();
} catch (e) {
print('错误:$e'); // 首先处理异常。
} finally {
cleanLlamaStalls(); // 然后清理。
}
要了解更多信息,请查看 核心库异常文档 。
断言
#在开发过程中,使用断言语句—— assert(<condition>, <optionalMessage>);
——如果布尔条件为假,则中断正常执行。
// 确保变量具有非空值。
assert(text != null);
// 确保值小于 100。
assert(number < 100);
// 确保这是一个 https URL。
assert(urlString.startsWith('https'));
要将消息附加到断言,请将字符串作为第二个参数添加到 assert
(可选地带 尾随逗号 ):
assert(urlString.startsWith('https'),
'URL ($urlString) 应该以 "https" 开头。');
assert
的第一个参数可以是任何解析为布尔值的表达式。如果表达式的值为真,则断言成功,执行继续。如果为假,则断言失败并抛出异常(一个 AssertionError
)。
断言究竟何时起作用?这取决于你使用的工具和框架:
- Flutter 在 调试模式 下启用断言。
- 仅限开发的工具,例如
webdev serve
,通常默认启用断言。 - 一些工具,例如
dart run
和dart compile js
,通过命令行标志支持断言:--enable-asserts
。
在生产代码中,断言被忽略,并且不会评估 assert
的参数。
除非另有说明,否则本网站上的文档反映的是 Dart 3.6.0。页面最后更新于 2025-02-05。 查看源代码 或 报告问题.