Erlang 程式設計/guards
外觀
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 時,分號 “; ” 表示布林 “或”,而逗號 “,” 表示布林 “與”。
the_answer_is(N) when N == 42, is_integer(N) -> true; geq_1_or_leq_2(N) when N >= 1; N =< 2 -> true;
在 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 ...