Dart基礎之異常

前言

一個成熟的計算機語言必須有異常機制。併發

爲何呢?ui

由於它能夠幫助開發者們更好的發現bug和解決bug。spa

接下來咱們來看下Dart的異常機制:線程

Dart代碼是支持拋出和捕獲異常的。異常一般是意外狀況發生時的錯誤指示。code

若是異常沒有捕獲,那麼isolate會接管已經掛起異常,而且一般狀況下isolate和它程序會被停止。orm

什麼是 isolate ???對象

isolate 是 隔離區 的英文,若是很難理解,咱們不妨把它理解成一個沙盒。內存

大多數計算機,即便在移動平臺上,也有多核CPU。 爲了利用全部這些核心,開發人員傳統上使用併發運行的共享內存線程。 可是,共享狀態併發容易出錯,而且可能致使代碼複雜化。ci

全部Dart代碼都在隔離區運行,而不是線程。 每一個隔離區都有本身的內存堆,確保不會從任何其餘隔離區訪問到本身隔離區的狀態。開發

與Java相比,Dart的全部異常都是未經檢查的異常。 方法不會聲明它們可能引起的異常,而且你不須要捕獲任何異常。

Dart提供了ExceptionError類型,以及許多預約義的子類型。 固然,你能夠定義本身的Exception。 而且Dart程序能夠拋出任何非null對象 (不單單是Exception和Error對象) 做爲異常對象。

throw

下面是拋出或者掛起一個異常的例子:

throw FormatException('Expected at least 1 section');
複製代碼

你也能夠拋出任意對象:

throw 'Out of llamas!';
複製代碼

注意:生產環境質量高的代碼一般會拋出已經實現了的錯誤或異常的類型。

由於拋出異常是一個表達式,因此能夠在=>語句中以及容許表達式的任何其餘地方拋出異常:

void distanceTo(Point other) => throw UnimplementedError();
複製代碼

catch

捕獲或捕捉異常會中止異常傳遞(除非你從新拋出異常)。 捕獲異常讓你有機會處理它:

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  buyMoreLlamas();
}
複製代碼

要處理可能拋出多種類型異常的代碼,能夠指定多個catch子句。 與拋出對象的類型匹配的第一個catch子句處理異常。 若是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或二者。 須要指定異常類型時使用。 在異常處理程序須要異常對象時使用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.
}
複製代碼
相關文章
相關標籤/搜索