跳轉到內容

Erlang 程式設計/guards

來自 Wikibooks,開放的書籍,開放的世界

← 函式 | 模組 →

Erlang Guards

[編輯 | 編輯原始碼]

Guard 結構

[編輯 | 編輯原始碼]

Erlang 中合法的 guards 是布林函式,放置在關鍵字 “when” 之後,箭頭 “->” 之前。 Guards 可能會出現在函式定義的一部分或 “receive”、'if'、“case” 和 “try/catch” 表示式中。

我們可以在函式定義中使用 guard
示例程式:guardian.erl

-module(guardian).
-compile(export_all).
   
the_answer_is(N) when N =:= 42 -> true;
the_answer_is(N) -> false.
   
% ============================================= >% 
%
% Example output:
%
% c(guardian).
% ok
%
% guardian:the_answer_is(42).
% true
%
% guardian:the_answer_is(21).
% false

和 Fun 定義

 F = fun
   (N) when N =:= 42 -> true;
   (N) -> false
 end.

receive 表示式

 receive
   {answer, N} when N =:= 42 -> true;
   {answer, N} -> false
 end.

if 表示式

 if 
   N =:= 42 -> true;
   true -> false
 end.

case 表示式

 case L of
   {answer, N} when N =:= 42 -> true;
   _ -> false
 end.

和 try/catch

 try find(L) of
    {answer, N} when N =:= 42 -> true;
    _ -> false
 catch
    {notanumber, R} when is_list(R) -> alist;
    {notanumber, R} when is_float(R) -> afloat
    _ -> noidea
 end.

你會注意到,在這些示例中,刪除 guard 並修改模式匹配(而不是使用 guard)會更清晰(在實際程式碼中)。

文學程式設計說明:以下劃線開頭(例如 “_”)的匿名匹配變數通常不推薦使用。 相反,使用一些描述性的變數名(例如 “_AnyNode”)會比較好。 另一方面,對於像這樣的教程程式碼來說,描述性變數比有幫助更讓人分心。

 case L of
   {node, N} when N =:= 42 -> true;
   _AnyNode -> false
 end.

多個 guards

[編輯 | 編輯原始碼]

可以在同一個函式定義或表示式中使用多個 guards。 當使用多個 guards 時,分號 “; ” 表示布林 “或”,而逗號 “,” 表示布林 “與”。

the_answer_is(N) when N == 42, is_integer(N) -> true;
geq_1_or_leq_2(N) when N >= 1; N =< 2 -> true;

Guard 函式

[編輯 | 編輯原始碼]

在 guard 中可以使用一些內建函式(BIF)。 基本上,我們只能用 is_type(A) 檢查型別,用 type_size() 或 length(L) 檢查列表的長度。

is_alive/0                     
is_boolean/1                    
is_builtin/3                    
is_constant/1                   
is_float/1                      
is_function/2      is_function(Z, Arity)               
is_function/1                  
is_integer/1                    
is_list/1                       
is_number/1                     
is_pid/1                        
is_port/1                      
is_record/3                    
is_record/2                     
is_reference/1                 
is_tuple/1      

tuple_size/1
is_binary/1
is_bitstring/1
bit_size/1
byte_size/1        
length(Z) > N 
map_size(M)
A > B
A < B
A == B
A =< B
A >= B
A /= B
A =:= B     exactly equal
A =/= B     exactly not equal

注意:所有 erlang 資料型別都有自然的排序。

atom < reference < port < pid < tuple < list ...
華夏公益教科書