錯誤也可以理解為異常,代表應用程式在執行過程中的發生了非預期的行為,常見異常比如有空指針、數組越界、網路超時、IO異常等,Dart語言也支持拋出和捕獲異常。和Java不同的是,Dart語言只有未檢測異常。Dart中的異常需要被捕獲並被處理,否則可能導致程式退出…… ...
Dart官方文檔:https://dart.dev/language/error-handling
重要說明:本博客基於Dart官網文檔,但並不是簡單的對官網進行翻譯,在覆蓋核心功能情況下,我會根據個人研發經驗,加入自己的一些擴展問題和場景驗證。
異常
和Java一樣,Dart也可以拋出異常,也可以捕獲異常。Dart異常如果未被捕獲,容易導致進程掛起和導致程式退出。所以,我們在編寫Dart程式時,需要特別關註異常。
和Java不同的是,Dart中的異常全部都是未檢測異常。如果一個方法沒有申明任何類型的異常,那麼我們就無需捕獲該方法的異常。
Dart提供了Exception
和Error
兩種異常的基礎類型,同時內置了其他一些它們的子類。我們也可以定義我們自己的異常類型,Dart可以把任何非空的對象當作異常拋出,且這些對象類型不一定是Exception
或Error
類型的子類(和Java有很大區別)。
throw拋出異常
Dart可以把任務非空對象當作異常拋出,但建議拋出的異常為Exception
或者Error
的子類,下麵是幾個代碼樣例:
throw FormatException('Expected at least 1 section');
throw 'Out of llamas!';
void distanceTo(Point other) => throw UnimplementedError();
catch捕獲異常
捕獲異常,一般有種目的:一是為了阻止異常繼續傳播,二是我們期望重新拋出異常。
捕獲異常的語法有幾種:
- on 異常類型 catch(異常對象)
- catch(異常對象)
- catch(異常對象, 異常堆棧)
捕獲異常後,我們可以進行一些處理。我們可以根據異常類型,捕獲多個異常。異常語句中若未定義異常類型,則捕獲所有異常,如下代碼樣例:
try {
breedMoreLlamas();
} on OutOfLlamasException {
// `OutOfLlamasException`類型的異常
buyMoreLlamas();
} on Exception catch (e) {
// `Exception`類型的異常
print('Unknown exception: $e');
} catch (e) {
// 其他的所有的異常
print('Something really unknown: $e');
}
異常堆棧類型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重新拋出異常
如下代碼樣例,當捕獲到異常之後,可以通過rethrow
重新拋出異常:
void misbehave() {
try {
dynamic foo = true;
print(foo++); // 製造異常
} catch (e) {
print('misbehave() partially handled ${e.runtimeType}.');
rethrow; // 重新拋出異常
}
}
void main() {
try {
misbehave();
} catch (e) {
print('main() finished handling ${e.runtimeType}.');
}
}
finally子句
當我們不論是否有異常發生,都行執行某個邏輯時,我們可用使用finally
子句。當發生異常時,首先執行catch
子句進行捕獲,若未被捕獲或者重新拋出異常,那麼這個異常會在執行完fianlly
之後被拋出。
try {
breedMoreLlamas();
} finally {
// 不論是否有異常發生,均會執行本邏輯
cleanLlamaStalls();
}
try {
breedMoreLlamas();
} catch (e) {
// 首先:捕獲異常
print('Error: $e');
} finally {
// 然後:執行本邏輯
cleanLlamaStalls();
}
斷言
在應用的開發階段,通過結果為false
的斷言語句(如:assert(<condition>, <optionalMessage>);
語句)來阻斷程式執行。幾種斷言語句的代碼樣例:
// `text`不能為null
assert(text != null);
// `number`必須小於100
assert(number < 100);
// `urlString`必須以`https`開頭
assert(urlString.startsWith('https'), 'URL ($urlString) should start with "https".');
斷言失敗(表達式結果為false
)時,拋出AssertionError
類型(Error
類型的子類)的異常。
斷言在以下場景下會生效:
- Flutter應用程式在debug模式(開發階段,開啟了斷言)。
- 類似於webdev等開發工具,預設開啟了斷言。
- 類似於
dart run
和dart compile js
等工具,且通過命令行增加了--enable-asserts
開啟斷言參數。
而在生產階段,斷言相關代碼被忽略,因此斷言會失效(不會執行)。
我的本博客原地址:https://ntopic.cn/p/2023101401
本文作者:奔跑的蝸牛,轉載請註明原文鏈接:https://ntopic.cn