
- Erlang 教程
- Erlang - 首頁
- Erlang - 概述
- Erlang - 環境
- Erlang - 基本語法
- Erlang - Shell
- Erlang - 資料型別
- Erlang - 變數
- Erlang - 運算子
- Erlang - 迴圈
- Erlang - 決策
- Erlang - 函式
- Erlang - 模組
- Erlang - 遞迴
- Erlang - 數字
- Erlang - 字串
- Erlang - 列表
- Erlang - 檔案 I/O
- Erlang - 原子
- Erlang - 對映
- Erlang - 元組
- Erlang - 記錄
- Erlang - 異常
- Erlang - 宏
- Erlang - 標頭檔案
- Erlang - 預處理器
- Erlang - 模式匹配
- Erlang - 守護程序
- Erlang - BIFS
- Erlang - 二進位制
- Erlang - 函式
- Erlang - 程序
- Erlang - 郵件
- Erlang - 資料庫
- Erlang - 埠
- Erlang - 分散式程式設計
- Erlang - OTP
- Erlang - 併發
- Erlang - 效能
- Erlang - 驅動程式
- Erlang - Web 程式設計
- Erlang 有用資源
- Erlang - 快速指南
- Erlang - 有用資源
- Erlang - 討論
Erlang - 異常
異常處理在任何程式語言中都是必需的,用於處理執行時錯誤,以便維護應用程式的正常流程。異常通常會中斷應用程式的正常流程,這就是為什麼我們需要在應用程式中使用異常處理的原因。
通常,當 Erlang 中發生異常或錯誤時,將顯示以下訊息。
{"init terminating in do_boot", {undef,[{helloworld,start,[],[]}, {init,start_it,1,[]},{init,start_em,1,[]}]}}
崩潰轉儲將寫入 -
erl_crash.dump init terminating in do_boot ()
在 Erlang 中,有三種類型的異常 -
錯誤 - 呼叫 erlang:error(Reason) 將終止當前程序中的執行,並在您捕獲它時包含最後呼叫的函式及其引數的堆疊跟蹤。這些是導致上面執行時錯誤的異常型別。
退出 - 有兩種型別的退出:'內部'退出和'外部'退出。內部退出是透過呼叫函式 exit/1 觸發的,並使當前程序停止執行。外部退出使用 exit/2 呼叫,並且與 Erlang 併發方面的多個程序有關。
丟擲 - 丟擲是一類異常,用於程式設計師可以預期處理的情況。與退出和錯誤相比,它們並沒有真正帶有任何“崩潰該程序!”的意圖,而是控制流程。當您在預期程式設計師處理丟擲時使用它們時,通常最好使用它們記錄模組中的用法。
try ... catch 是一種評估表示式的 方法,同時允許您處理成功的情況以及遇到的錯誤。
try catch 表示式的通用語法如下。
語法
try Expression of SuccessfulPattern1 [Guards] -> Expression1; SuccessfulPattern2 [Guards] -> Expression2 catch TypeOfError:ExceptionPattern1 -> Expression3; TypeOfError:ExceptionPattern2 -> Expression4 end
try 和 of 之間的表示式被稱為受保護的。這意味著在該呼叫中發生的任何型別的異常都將被捕獲。try ... of 和 catch 之間的模式和表示式與 case ... of 的行為完全相同。
最後,是 catch 部分 - 在這裡,您可以將 TypeOfError 替換為 error、throw 或 exit,分別對應我們本章中看到的每種型別。如果未提供型別,則假定為 throw。
以下是 Erlang 中的一些錯誤和錯誤原因 -
錯誤 | 錯誤型別 |
---|---|
badarg | 錯誤的引數。引數的資料型別錯誤,或者格式錯誤。 |
badarith | 算術表示式中的錯誤引數。 |
{badmatch,V} | 匹配表示式的評估失敗。值 V 沒有匹配。 |
function_clause | 在評估函式呼叫時找不到匹配的函式子句。 |
{case_clause,V} | 在評估 case 表示式時找不到匹配的分支。值 V 沒有匹配。 |
if_clause | 在評估 if 表示式時找不到 true 分支。 |
{try_clause,V} | 在評估 try 表示式的 of 部分時找不到匹配的分支。值 V 沒有匹配。 |
undef | 在評估函式呼叫時找不到函式。 |
{badfun,F} | 函式 F 有問題 |
{badarity,F} | 函式應用於錯誤數量的引數。F 描述了函式和引數。 |
timeout_value | receive..after 表示式中的超時值計算結果不是整數或無限大。 |
noproc | 嘗試連結到不存在的程序。 |
下面是一個關於如何使用這些異常以及如何執行操作的示例。
第一個函式生成所有可能的異常型別。
然後我們編寫一個包裝器函式,在 try...catch 表示式中呼叫 generate_exception。
示例
-module(helloworld). -compile(export_all). generate_exception(1) -> a; generate_exception(2) -> throw(a); generate_exception(3) -> exit(a); generate_exception(4) -> {'EXIT', a}; generate_exception(5) -> erlang:error(a). demo1() -> [catcher(I) || I <- [1,2,3,4,5]]. catcher(N) -> try generate_exception(N) of Val -> {N, normal, Val} catch throw:X -> {N, caught, thrown, X}; exit:X -> {N, caught, exited, X}; error:X -> {N, caught, error, X} end. demo2() -> [{I, (catch generate_exception(I))} || I <- [1,2,3,4,5]]. demo3() -> try generate_exception(5) catch error:X -> {X, erlang:get_stacktrace()} end. lookup(N) -> case(N) of 1 -> {'EXIT', a}; 2 -> exit(a) end.
如果我們像 helloworld:demo() 那樣執行程式,我們將得到以下輸出 -
輸出
[{1,normal,a}, {2,caught,thrown,a}, {3,caught,exited,a}, {4,normal,{'EXIT',a}}, {5,caught,error,a}]