我在网上发现了这段代码:
is_char(Ch) ->
if Ch < 0 -> false;
Ch > 255 -> false;
true -> true
end.
is_string(Str) ->
case is_list(Str) of
false -> false;
true -> lists:all(is_char, Str)
end.
它是我梦寐以求的守卫,因为它检查输入是否是一个字符串 - 但是,我不允许在erlang中使用它,为什么会这样?是否有解决方法?
我希望能够写出如下内容:
Fun(Str) when is_string(Str) -> Str;
Fun(Int) when is_integer(Int) -> io:format("~w", [Int]).
甚至更好地在消息上使用它。
答案 0 :(得分:10)
您不得在警卫中使用用户定义的功能。这是因为警卫中的功能必须没有副作用(例如在你的函数中使用io:format
)。在警卫中,您仅限于以下内容:
is_atom
,is_constant
,is_float
,is_integer
,is_list
,is_number
,is_pid
,is_port
,is_reference
,is_tuple
,is_binary
,is_function
,is_record
),not
,and
,or
,andalso
,orelse
,,
,;
),< / LI>
>
,>=
,<
,=<
,=:=
,==
,=/=
,{{ 1}}),/=
,+
,-
,*
,div
),rem
,band
,bor
,bxor
,bnot
,bsl
),bsr
,abs/1
,element/2
,hd/1
,length/1
,node/1,2
,{{ 1}},round/1
,size/1
,tl/1
)答案 1 :(得分:5)
不允许在警卫中使用用户定义函数的另一个原因是,警卫中的错误处理方式与“普通”函数不同。在一个警卫中,错误不会产生异常,它只会导致警卫本身失败。
警卫不是真正的表达,而是测试。