在案例模式匹配中调用函数是非法模式吗?
Posted
技术标签:
【中文标题】在案例模式匹配中调用函数是非法模式吗?【英文标题】:Calling functions within case pattern matching is illegal pattern? 【发布时间】:2017-05-19 10:12:29 【问题描述】:-module(erltoy).
-compile(export_all).
isFive(5) -> true;
isFive(_) -> false.
foo(X) ->
case X of
isFive(X) -> true;
3 -> false;
_ -> nope
end.
1> c(erltoy).
erltoy.erl:9: illegal pattern
error
我不能在模式匹配中调用函数吗?
【问题讨论】:
【参考方案1】:isFive(X) -> true; 包含无法在编译时计算为常量的表达式,因此不是有效的pattern。如果算术表达式同时满足以下两个条件,则可以在模式中使用算术表达式:
它只使用数字或位运算符。 编译时其值可以计算为常数。参见 Erlang 参考手册中的这个示例
case Value, Result of
?THRESHOLD+1, ok -> ...
【讨论】:
【参考方案2】:要完成@byaruhaf 的回答,在编译 时,case 子句的左边部分不需要是常量。以下代码是有效的,显然,Temp
在编译时是未知的(但 foo(5) 的计算结果为 nope!)。
-module(erltoy).
-compile(export_all).
isFive(5) -> true;
isFive(_) -> false.
foo(X) ->
Temp = isFive(X),
case X of
Temp -> true;
3 -> false;
_ -> nope
end.
左边部分甚至没有必要在执行时绑定,例如这也是有效的,有I
在case评估前是未绑定的,在模式匹配时是绑定的:
get_second_element_of_3_terms_tuple_if_pos_integer(X) ->
case X of
_,I,_ when is_integer(I), I>0 -> true,I;
_ -> false
end.
案例的左边部分必须是带有可选保护序列的有效模式。
一个有效的模式是一个 erlang 术语,它可能包含未绑定的变量,如果它们遵守 2 个条件,它也可能包含算术表达式
它只使用数字或位运算符。 编译时其值可以计算为常数。给出了保护序列的定义there in erlang documentation
最后一点,编写示例中给出的那种测试函数的常用 erlang 方法是使用不同的函数头,就像你为 isFive/1 定义所做的那样。
【讨论】:
以上是关于在案例模式匹配中调用函数是非法模式吗?的主要内容,如果未能解决你的问题,请参考以下文章