2012-06-24 27 views
7

tôi đến accross mã này trên trang web:Tôi có thể tự bảo vệ mình tại Erlang không?

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. 

là Guard tôi alwais mơ đi, ở chỗ nó kiểm tra nếu một đầu vào là một chuỗi của nó - làm thế nào bao giờ, tôi không được phép sử dụng nó trong erlang, tại sao thế này? Và có một công việc xung quanh?

Tôi muốn để có thể viết những thứ như:

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

hoặc thậm chí tốt hơn sử dụng nó trên tin nhắn.

+4

Không vi phạm nhưng cách tốt hơn để kiểm tra chuỗi là phương pháp: 'io_lib: printable_list/1' và' io_lib: printable_unicode_list/1' được sử dụng kết hợp. –

+0

Xem thêm [this] (http://stackoverflow.com/questions/10861347/why-comparing-function-results-is-an-illegal-guard-exception-in-erlang), [this] (http: // stackoverflow.com/questions/6505213/is-there-a-way-to-use-local-function-in-guard), [this] (http://stackoverflow.com/questions/6927632/checking-for-membership -in-an-erlang-guard), [this] (http: // stackoverflow.com/questions/2241340/không thể sử dụng-chức năng-gọi-trong-chức năng-guard) và [this] (http://stackoverflow.com/questions/7474894/use-of-function-in-guard-not -cho phép-đề xuất-cho-thay-thực hiện-w) câu hỏi. – legoscia

Trả lời

9

Bạn không được phép sử dụng các chức năng do người dùng xác định trong các vệ sĩ. Đó là bởi vì các chức năng trong các vệ sĩ phải được miễn phí từ các tác dụng phụ (chẳng hạn như sử dụng io:format trong các chức năng của bạn). Trong bảo vệ, bạn được giới hạn như sau:

  • BIFs sử dụng để kiểm tra loại (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),
  • toán tử boolean (not, and, or, andalso, orelse, ,, ;),
  • toán tử quan hệ (>, >=, <, =<, =:=, ==, =/=, /=),
  • toán tử số học (+, -, *, div, rem),
  • toán tử Bitwise (band, bor, bxor, bnot, bsl, bsr),
  • khác BIFs tha t được tự do tác dụng phụ (abs/1, element/2, hd/1, length/1, node/1,2, round/1, size/1, tl/1, trunc/1, self/0)
+4

Hmm, có vẻ như việc kiểm tra các tác dụng phụ sẽ là một thủ thuật tĩnh-analycis khá dễ dàng ... –

+5

@MartinKristiansen Không thực sự, bởi vì bất kỳ mã nào trong các mô-đun có thể được thay đổi hoặc thay thế khi chạy. –

+0

@alexeyRomanov: Bạn hoàn toàn đúng - nhưng có lẽ sau đó hạn chế sử dụng các chức năng của BIF và chỉ bên trong mô-đun hiện tại :-) –

5

Một lý do không cho phép hàm do người dùng định nghĩa trong bảo vệ là lỗi được xử lý khác nhau trong bảo vệ hơn trong các chức năng "bình thường". Trong một bảo vệ một lỗi nào không tạo ra một ngoại lệ, nó chỉ gây ra bảo vệ chính nó thất bại.

Vệ sĩ không thực sự là biểu thức nhưng kiểm tra.

Các vấn đề liên quan