Erlang - Ngoại lệ
Xử lý ngoại lệ được yêu cầu trong bất kỳ ngôn ngữ lập trình nào để xử lý các lỗi thời gian chạy để có thể duy trì luồng bình thường của ứng dụng. Ngoại lệ thường làm gián đoạn luồng thông thường của ứng dụng, đó là lý do tại sao chúng ta cần sử dụng xử lý Ngoại lệ trong ứng dụng của mình.
Thông thường khi một ngoại lệ hoặc lỗi xảy ra trong Erlang, thông báo sau sẽ được hiển thị.
{"init terminating in do_boot", {undef,[{helloworld,start,[],[]},
{init,start_it,1,[]},{init,start_em,1,[]}]}}
Crash dump sẽ được ghi vào -
erl_crash.dump
init terminating in do_boot ()
Ở Erlang, có 3 loại ngoại lệ -
Error - Gọi điện erlang:error(Reason)sẽ kết thúc quá trình thực thi trong quy trình hiện tại và bao gồm một dấu vết ngăn xếp của các hàm cuối cùng được gọi với các đối số của chúng khi bạn nắm bắt nó. Đây là những loại ngoại lệ gây ra lỗi thời gian chạy ở trên.
Exists- Có hai loại lối ra: lối ra 'nội bộ' và lối ra 'bên ngoài'. Các lối ra bên trong được kích hoạt bằng cách gọi hàmexit/1và làm cho quá trình hiện tại ngừng thực thi. Các lối ra bên ngoài được gọi bằngexit/2 và phải thực hiện với nhiều quy trình trong khía cạnh đồng thời của Erlang.
Throw- Một cú ném là một lớp ngoại lệ được sử dụng cho các trường hợp mà người lập trình có thể xử lý. So với các lần thoát và lỗi, chúng không thực sự mang lại bất kỳ 'sự cố quá trình đó!' ý định đằng sau chúng, nhưng đúng hơn là chúng kiểm soát luồng. Khi bạn sử dụng lệnh ném trong khi mong đợi lập trình viên xử lý chúng, thông thường bạn nên ghi lại việc sử dụng chúng trong một mô-đun sử dụng chúng.
A try ... catch là một cách để đánh giá một biểu thức đồng thời cho phép bạn xử lý trường hợp thành công cũng như các lỗi gặp phải.
Cú pháp chung của biểu thức try catch như sau.
Cú pháp
try Expression of
SuccessfulPattern1 [Guards] ->
Expression1;
SuccessfulPattern2 [Guards] ->
Expression2
catch
TypeOfError:ExceptionPattern1 ->
Expression3;
TypeOfError:ExceptionPattern2 ->
Expression4
end
Biểu thức ở giữa try and ofđược cho là được bảo vệ. Điều này có nghĩa là bất kỳ loại ngoại lệ nào xảy ra trong cuộc gọi đó sẽ bị bắt. Các mẫu và biểu thức ở giữatry ... of and catch hành xử theo cách giống hệt như một case ... of.
Cuối cùng là phần bắt - ở đây, bạn có thể thay thế TypeOfErrorbởi một trong hai lỗi, ném hoặc thoát, đối với từng loại tương ứng mà chúng ta đã thấy trong chương này. Nếu không có loại nào được cung cấp, thì một lần ném được giả định.
Sau đây là một số lỗi và lý do lỗi trong Erlang -
lỗi | Loại lỗi |
---|---|
badarg | Lập luận tồi. Đối số có kiểu dữ liệu sai hoặc được tạo sai. |
badarith | Đối số sai trong một biểu thức số học. |
{badmatch, V} | Đánh giá biểu thức đối sánh không thành công. Giá trị V không khớp. |
function_clause | Không tìm thấy mệnh đề hàm phù hợp khi đánh giá một lệnh gọi hàm. |
{case_clause, V} | Không tìm thấy nhánh phù hợp khi đánh giá một biểu thức chữ hoa chữ thường. Giá trị V không khớp. |
mệnh đề if | Không tìm thấy nhánh đúng khi đánh giá biểu thức if. |
{try_clause, V} | Không tìm thấy nhánh phù hợp khi đánh giá phần của một biểu thức thử. Giá trị V không khớp. |
undef | Không thể tìm thấy hàm khi đánh giá một lệnh gọi hàm .. |
{badfun, F} | Có gì đó không ổn với điểm F vui nhộn |
{xấu tính, F} | Một niềm vui được áp dụng cho số đối số sai. F mô tả niềm vui và các lập luận. |
timeout_value | Giá trị thời gian chờ trong biểu thức nhận.. after được đánh giá thành giá trị khác với số nguyên hoặc vô hạn. |
noproc | Đang cố gắng liên kết với một quy trình không tồn tại. |
Sau đây là một ví dụ về cách các ngoại lệ này có thể được sử dụng và cách mọi thứ được thực hiện.
Hàm đầu tiên tạo ra tất cả các kiểu ngoại lệ có thể có.
Sau đó, chúng tôi viết một hàm wrapper để gọi generate_exception trong một biểu thức try ... catch.
Thí dụ
-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.
Nếu chúng ta chạy chương trình dưới dạng helloworld: demo (). , chúng ta sẽ nhận được kết quả sau:
Đầu ra
[{1,normal,a},
{2,caught,thrown,a},
{3,caught,exited,a},
{4,normal,{'EXIT',a}},
{5,caught,error,a}]