我在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) ->
Run Code Online (Sandbox Code Playgroud)
我在这里使用的是orelse,而且它使得代码的可读性差得多,而且通常更长.
有没有办法实现相同的保护逻辑使用,和; 只要?
不,你需要保留一些orelse和andalso,因为当使用,和时;,你基本上有许多;由几个条件(分开)组成的备选方案,,并且至少有一个备选方案中的每个条件都必须是真正.在这个例子中,你几乎有相反的情况:对于每个参数,你希望其中一个条件为真.
换句话说,像这样的警卫:
A, B; C, D
Run Code Online (Sandbox Code Playgroud)
是(几乎1)相当于:
(A andalso B) orelse (C andalso D)
Run Code Online (Sandbox Code Playgroud)
并且没有办法像(A orelse B) andalso (C orelse D)没有使用这些运算符那样做.
但是,您可以将此示例缩短一点:
is_list(List)是多余的,因为length(List)如果List不是列表就会失败.在警卫中,"失败"并不意味着抛出错误; 它只是意味着该条款不匹配.is_integer(Number)几乎是多余的,因为你也有Number >= 10 andalso Number =< 50.在Erlang中,可以比较任何两个术语的大小,因此如果Number在这个范围内,它肯定是一个数字.(但它可能是浮点数而不是整数.)而不是is_record(Record, my_record),您可以匹配函数头中的记录:
my_fun(List, Number, OptionalList, Record = #my_record{})
Run Code Online (Sandbox Code Playgroud)1如果A或B将抛出异常,则orelse版本将不匹配,而;如果该C, D部分匹配,则版本将匹配.例如,此函数返回b:
foo() when 1/0 == 1 orelse true ->
a;
foo() when 1/0 == 1; true ->
b.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
168 次 |
| 最近记录: |