我可以在Erlang中制作自己的Guards吗?

时间:2012-06-24 11:36:08

标签: erlang guard

我在网上发现了这段代码:

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]).

甚至更好地在消息上使用它。

2 个答案:

答案 0 :(得分:10)

您不得在警卫中使用用户定义的功能。这是因为警卫中的功能必须没有副作用(例如在你的函数中使用io:format)。在警卫中,您仅限于以下内容:

  • 用于类型测试的BIF(is_atomis_constantis_floatis_integeris_listis_numberis_pidis_portis_referenceis_tupleis_binaryis_functionis_record),
  • 布尔运算符(notandorandalsoorelse,;),< / LI>
  • 关系运算符(>>=<=<=:====/=,{{ 1}}),
  • 算术运算符(/=+-*div),
  • 按位运算符(rembandborbxorbnotbsl),
  • 其他没有副作用的BIF(bsrabs/1element/2hd/1length/1node/1,2,{{ 1}},round/1size/1tl/1

答案 1 :(得分:5)

不允许在警卫中使用用户定义函数的另一个原因是,警卫中的错误处理方式与“普通”函数不同。在一个警卫中,错误会产生异常,它只会导致警卫本身失败。

警卫不是真正的表达,而是测试