Erlang 移除长防护装置中的orelse和andalso

Erlang 移除长防护装置中的orelse和andalso,erlang,Erlang,我正在用erlang编写一个函数,它应该能够以不同的顺序和格式接受不同的参数集,并且我使用非常严格的保护来确保正确的匹配 对我来说,写这样一篇长篇大论的文章并不少见: my_fun(List, Number, OptionalList, Record) when is_list(List) andalso length(List) >= 5, is_integer(Number) andalso Number >= 10 andalso Number =< 50 o

我正在用erlang编写一个函数,它应该能够以不同的顺序和格式接受不同的参数集,并且我使用非常严格的保护来确保正确的匹配

对我来说,写这样一篇长篇大论的文章并不少见:

my_fun(List, Number, OptionalList, Record)
when is_list(List) andalso length(List) >= 5, 
     is_integer(Number) andalso Number >= 10 andalso Number =< 50 orelse Number =:= undefined, 
     is_list(OptionalList) orelse OptionalList =:= undefined, 
     is_record(Record, my_record) ->
A, B; C, D
my_fun(列表、编号、选项列表、记录)
当_list(list)和also length(list)>=5时,
is_integer(Number)and Also Number>=10 and Also Number=<50或Else Number=:=未定义,
is_list(OptionalList)或LSE OptionalList=:=未定义,
是记录(记录,我的记录)->
我在这里经常使用orelse和andalso,这使得代码的可读性大大降低,而且通常更长


是否有方法使用和实现相同的保护逻辑;只有?

不,您需要保留一些
以及
,因为在使用
,基本上有许多备选方案(由
分隔;
)由几个条件组成(由
分隔),并且至少一个备选方案中的每个条件都必须为真。在本例中,情况几乎相反:对于每个参数,您希望其中一个条件为true

换句话说,像这样的守卫:

my_fun(List, Number, OptionalList, Record)
when is_list(List) andalso length(List) >= 5, 
     is_integer(Number) andalso Number >= 10 andalso Number =< 50 orelse Number =:= undefined, 
     is_list(OptionalList) orelse OptionalList =:= undefined, 
     is_record(Record, my_record) ->
A, B; C, D
是(几乎1)等于:

(A andalso B) orelse (C andalso D)
如果不使用这些运算符,就无法执行类似于
(A orelse B)和also(C orelse D)
的操作

不过,您可以将此示例缩短一点:

  • is\u list(list)
    是多余的,因为如果
    list
    不是列表,
    length(list)
    将失败。在守卫中,“失败”并不意味着犯错误;这只是意味着条款不匹配
  • 是整数(Number)
    几乎是多余的,因为您还拥有
    Number>=10和<50
    。在Erlang中,可以比较任意两个术语的大小,因此如果
    Number
    在这个范围内,它肯定是一个数字。(不过,它可以是一个浮点数,而不是一个整数。)
  • 您可以在函数头中匹配一条记录,而不是
    is\u record(record,my\u record)

    my_fun(List, Number, OptionalList, Record = #my_record{})
    

1如果
A
B
将引发异常,则
orelse
版本将不匹配,而
C,D
部分匹配,则代码>版本将匹配。例如,此函数返回
b

foo() when 1/0 == 1 orelse true ->
    a;
foo() when 1/0 == 1; true ->
    b.

不,您需要保留一些
以及
,因为在使用
,基本上有许多备选方案(由
分隔;
)由几个条件组成(由
分隔),并且至少一个备选方案中的每个条件都必须为真。在本例中,情况几乎相反:对于每个参数,您希望其中一个条件为true

换句话说,像这样的守卫:

my_fun(List, Number, OptionalList, Record)
when is_list(List) andalso length(List) >= 5, 
     is_integer(Number) andalso Number >= 10 andalso Number =< 50 orelse Number =:= undefined, 
     is_list(OptionalList) orelse OptionalList =:= undefined, 
     is_record(Record, my_record) ->
A, B; C, D
是(几乎1)等于:

(A andalso B) orelse (C andalso D)
如果不使用这些运算符,就无法执行类似于
(A orelse B)和also(C orelse D)
的操作

不过,您可以将此示例缩短一点:

  • is\u list(list)
    是多余的,因为如果
    list
    不是列表,
    length(list)
    将失败。在守卫中,“失败”并不意味着犯错误;这只是意味着条款不匹配
  • 是整数(Number)
    几乎是多余的,因为您还拥有
    Number>=10和<50
    。在Erlang中,可以比较任意两个术语的大小,因此如果
    Number
    在这个范围内,它肯定是一个数字。(不过,它可以是一个浮点数,而不是一个整数。)
  • 您可以在函数头中匹配一条记录,而不是
    is\u record(record,my\u record)

    my_fun(List, Number, OptionalList, Record = #my_record{})
    

1如果
A
B
将引发异常,则
orelse
版本将不匹配,而
C,D
部分匹配,则代码>版本将匹配。例如,此函数返回
b

foo() when 1/0 == 1 orelse true ->
    a;
foo() when 1/0 == 1; true ->
    b.

考虑使用宏?<代码>何时?iSixEngEngIn范围(数字,10, 50)< /代码>,例如,考虑使用宏?<例如,代码>何时?是在范围内的整数(数字,10,50)