Can I make my own Guards in Erlang?

人盡茶涼 提交于 2019-11-28 07:28:21

问题


I came accross this code on the web:

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.

Its is the Guard I alwais dreamed off, in that it checks if an input is a string -- how ever, I'm not allowed to use it in erlang, why is this? And is there a work around?

I would like to be able to write stuff like:

Fun(Str) when is_string(Str) -> Str;
Fun(Int) when is_integer(Int) -> io:format("~w", [Int]).

or even better use it on messages.


回答1:


You are not allowed to use user defined functions in the guards. It is because the functions in the guards have to be free from side effects (such as using io:format in your functions). In guards, you are limited to the following:

  • BIFs used for type tests (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),
  • boolean operators (not, and, or, andalso, orelse, ,, ;),
  • relational operators (>, >=, <, =<, =:=, ==, =/=, /=),
  • arithmetic operators (+, -, *, div, rem),
  • bitwise operators (band, bor, bxor, bnot, bsl, bsr),
  • other BIFs that are free of side effects (abs/1, element/2, hd/1, length/1, node/1,2, round/1, size/1, tl/1, trunc/1, self/0)



回答2:


Another reason for not allowing user defined functions in guards is that errors are handled differently in guards than in "normal" functions. In a guard an error does not generate an exception, it only causes the guard itself to fail.

Guards are not really expressions but tests.



来源:https://stackoverflow.com/questions/11177109/can-i-make-my-own-guards-in-erlang

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!