Dart 简明教程 - 05 - Exceptions

1,177 阅读2分钟

本系列教程大多翻译自 Dart 官网,因本人英语水平有限,可能有些地方翻译不准确,还请各位大佬斧正。如需转载请标明出处,谢绝 CSDN 爬虫党。

Exceptions (异常)

你编写的 Dart 代码可以抛出和捕获异常。异常是指示了一些出乎意料的错误。如果异常没有被捕获,会一直往上层传递,直到程序崩溃并停止执行。

相对于 Java, Dart 所有的异常都是未检查的。所以调用方法时可能会抛出异常,但并不强制要求你捕获。

Dart 提供了 ExceptionError 两种类型,以及许多重新定义的子类。你可以定义自己的异常。但是,异常并不只有 Exception 和 Error 两种对象,Dart 程序可以抛出任何非 null 的对象当做异常。

Throw

这是抛出异常的例子:

throw FormatException('Expected at least 1 section');

你也可以抛出任意对象:

throw 'Out of llamas!';

Note: 高质量的代码,通常抛出 ErrorException 的实例。

因为抛出异常是个表达式,你可以写在箭头函数中:

void distanceTo(Point other) => throw UnimplementedError();

Catch

捕获异常,防止异常继续传递(除非你又重新抛出),并提供一个机会让你处理这个异常。

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  buyMoreLlamas();
}

如果抛出的异常有很多种类型,你可以 指定捕获的分支去处理。第一个捕获分支会匹配抛出的对象类型并处理。如果捕获分支没有匹配,会统一交给最后的 catch 去处理。

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  // A specific exception
  buyMoreLlamas();
} on Exception catch (e) {
  // Anything else that is an exception
  print('Unknown exception: $e');
} catch (e) {
  // No specified type, handles all
  print('Something really unknown: $e');
}

像上述代码展示的那样,你可以使用 oncatch 或两者一起使用。当你需要指定异常的对象时,使用 on。 但你需要处理异常的时候,使用 catch

你可以向 catch() 传一到两个参数。第一个参数是异常的信息,第二个参数是异常的堆栈跟踪(StackTrace)。

try {
  // ···
} on Exception catch (e) {
  print('Exception details:\n $e');
} catch (e, s) {
  print('Exception details:\n $e');
  print('Stack trace:\n $s');
}

处理异常的时候,还可以使用 rethrow 关键字,重新抛出这个异常,交由其他捕获函数使用。

void misbehave() {
  try {
    dynamic foo = true;
    print(foo++); // Runtime error
  } catch (e) {
    print('misbehave() partially handled ${e.runtimeType}.');
    rethrow; // Allow callers to see the exception.
  }
}

void main() {
  try {
    misbehave();
  } catch (e) {
    print('main() finished handling ${e.runtimeType}.');
  }
}

Finally

使用finally 分支,会确保代码运行过程中,无论是否抛出了异常都会执行。如果 catch 没有匹配到异常,异常会直接走到 finally 分支:

try {
  breedMoreLlamas();
} finally {
  // Always clean up, even if an exception is thrown.
  cleanLlamaStalls();
}

finally 分支会在 catch 分支之后继续执行:

try {
  breedMoreLlamas();
} catch (e) {
  print('Error: $e'); // Handle the exception first.
} finally {
  cleanLlamaStalls(); // Then clean up.
}

更多详情请移步 Exceptions

系列文章:

Dart 简明教程 - 01 - Concepts & Variables
Dart 简明教程 - 02 - Functions
Dart 简明教程 - 03 - Operators
Dart 简明教程 - 04 - Control flow statements
Dart 简明教程 - 05 - Exceptions
Dart 简明教程 - 06 - Classes
Dart 简明教程 - 07 - Generics
Dart 简明教程 - 08 - Libraries and visibility
Dart 简明教程 - 09 - Asynchrony support
Dart 简明教程 - 10 - Generators & Isolates & Typedefs & Metadata...