定义保护序列以及什么是有效的保护表达式?

Define Guard Sequence And What Are The Valid Guard Expressions?

我想知道 Guard 序列以及 Erlang 中有效的 Guard 表达式是什么?

Guard Sequences

A guard sequence is a sequence of guards, separated by semicolon (;). The guard sequence is true if at least one of the guards is true. (The remaining guards, if any, are not evaluated.)

Guard1;...;GuardK

示例:

go(X,Y) when X==1;Y==2 ->
   io:format("Yes~n").

在shell:

2> a:go(1, 2).
Yes
ok
3> a:go(1, 3).
Yes
ok
4> a:go(4, 2).
Yes
ok
5> a:go(4, 3).
** exception error: no function clause matching 
                a:go(4,3) (a.erl, line 4)

所以,分号就像 OR

A guard is a sequence of guard expressions, separated by comma (,). The guard is true if all guard expressions evaluate to true.

GuardExpr1,...,GuardExprN

示例:

go(X,Y,Z) when X==1,Y==2, is_atom(Z) ->
    io:format("Yes~n").

在shell:

8> a:go(1, 3, a).
** exception error: no function clause matching 
                    a:go(1,3,a) (a.erl, line 4)
9> a:go(1, 2, a).
Yes
ok

所以,逗号就像 AND.

Guard Expressions

The set of valid guard expressions is a subset of the set of valid Erlang expressions. The reason for restricting the set of valid expressions is that evaluation of a guard expression must be guaranteed to be free of side effects. Valid guard expressions are the following:

Variables
Constants (atoms, integer, floats, lists, tuples, records, binaries, and maps)
Expressions that construct atoms, integer, floats, lists, tuples, records, binaries, and maps
Expressions that update a map
The record epxressions Expr#Name.Field and #Name.Field
Calls to the BIFs specified in tables Type Test BIFs and Other BIFs Allowed in Guard Expressions
Term comparisons
Arithmetic expressions
Boolean expressions
Short-circuit expressions (andalso/orelse)

Type Test BIFs:

    is_atom/1
    is_binary/1
    is_bitstring/1
    is_boolean/1
    is_float/1
    is_function/1
    is_function/2
    is_integer/1
    is_list/1
    is_map/1
    is_number/1
    is_pid/1
    is_port/1
    is_record/2
    is_record/3
    is_reference/1
    is_tuple/1

Notice that most type test BIFs have older equivalents, without the is_ prefix. These old BIFs are retained for backwards compatibility only and are not to be used in new code. They are also only allowed at top level. For example, they are not allowed in Boolean expressions in guards.

Other BIFs Allowed in Guard Expressions:

abs(Number)
bit_size(Bitstring)
byte_size(Bitstring)
element(N, Tuple)
float(Term)
hd(List)
length(List)
map_get(Key, Map)
map_size(Map)
node()
node(Pid|Ref|Port)
round(Number)
self()
size(Tuple|Bitstring)
tl(List)
trunc(Number)
tuple_size(Tuple)

If an arithmetic expression, a Boolean expression, a short-circuit expression, or a call to a guard BIF fails (because of invalid arguments), the entire guard fails. If the guard was part of a guard sequence, the next guard in the sequence (that is, the guard following the next semicolon) is evaluated.

这个:

A guard sequence is a sequence of guards, separated by semicolon (;).

给你这个:

GuardSequence = Guard1;Guard2;Guard3

什么是Guard?这句话:

A guard is a sequence of guard expressions, separated by comma (,).

给你这个:

Guard1 = GuardExpr1, GuardExpr2, GuardExpr3

什么是 guard expression?这句话:

The set of valid guard expressions is...

给你这样的东西:

GuardExpr1 = (X==1)
GuardExpr2 = (Y==2)
GuardExpr3  = is_atom(Z)

现在,将 GuardExpr 替换到此行中:

 Guard1 = GuardExpr1, GuardExpr2, GuardExpr3

给你:

 Guard1 =   X==1, Y==2, is_atom(Z)

现在,将 Guard1 代入这一行:

 GuardSequence = Guard1;Guard2;Guard3

给你:

 GuardSequence = X==1, Y==2, is_atom(Z)

如果你还有 Guard2 和 Guard3,它们看起来像这样:

 Guard2 =  is_integer(X)
 Guard3 =  element(Y, Tuple)

那么 GuardSequence 将如下所示:

GuardSequence = X==1, Y==2, is_atom(Z); is_integer(X); element(Y, Tuple)

好吗??!