內容

例外狀況

#

Dart 程式碼可以拋出和捕捉例外狀況。例外狀況是表示發生意外事件的錯誤。如果沒有捕捉到例外狀況,則會暫停引發例外狀況的 隔離區,而且通常會終止隔離區及其程式。

與 Java 相反,Dart 的所有例外狀況都是未檢查的例外狀況。方法不會宣告它們可能會拋出的例外狀況,而且不需要捕捉任何例外狀況。

Dart 提供 ExceptionError 型別,以及許多預先定義的子型別。當然,你可以定義自己的例外狀況。不過,Dart 程式可以拋出任何非 null 物件(不只是 Exception 和 Error 物件)作為例外狀況。

拋出

#

以下是拋出(或引發)例外狀況的範例

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

您也可以拋出任意物件

dart
throw 'Out of llamas!';

因為拋出例外情況是一種表達式,所以您可以在 => 陳述式中拋出例外情況,以及允許表達式的任何其他地方

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

捕捉

#

捕捉或擷取例外情況會停止例外情況傳播 (除非您重新拋出例外情況)。捕捉例外情況讓您有機會處理它

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

若要處理可能會拋出多種型別例外情況的程式碼,您可以指定多個捕捉子句。第一個與拋出物件型別相符的捕捉子句會處理例外情況。如果捕捉子句未指定型別,該子句可以處理任何型別的拋出物件

dart
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 物件)。

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

若要部分處理例外情況,同時允許它傳播,請使用 rethrow 關鍵字。

dart
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 子句。如果沒有 catch 子句與例外情況相符,例外情況會在 finally 子句執行後傳播

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

finally 子句會在任何相符的 catch 子句後執行

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

若要深入了解,請查看 核心函式庫例外情況文件

宣告

#

在開發期間,請使用斷言陳述式— assert(<condition>, <optionalMessage>); —如果布林條件為 false,則中斷正常執行。

dart
// Make sure the variable has a non-null value.
assert(text != null);

// Make sure the value is less than 100.
assert(number < 100);

// Make sure this is an https URL.
assert(urlString.startsWith('https'));

若要將訊息附加至斷言,請將字串新增為 assert 的第二個引數 (選擇性地加上 尾隨逗號)

dart
assert(urlString.startsWith('https'),
    'URL ($urlString) should start with "https".');

assert 的第一個引數可以是任何解析為布林值的表達式。如果表達式的值為 true,斷言會成功且執行會繼續。如果為 false,斷言會失敗並拋出例外情況 (一個 AssertionError)。

斷言究竟在何時運作?這取決於您使用的工具和架構

在生產程式碼中,斷言會被忽略,且不會評估傳遞給 assert 的引數。