2012-06-24 108 views
7

我來到防空火炮在網絡上此代碼:我可以在Erlang做我自己的衛兵嗎?

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. 

它是保護我alwais夢見掉,因爲它會檢查是否輸入是一個字符串 - 怎麼過的,我不能用它在erlang中,這是爲什麼?有沒有解決辦法?

我希望能夠寫這樣的東西:

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

甚至更​​好的使用它的消息。

+4

沒有冒犯,但是,對字符串進行測試的更好方法是將'io_lib:printable_list/1'和'io_lib:printable_unicode_list/1'組合使用。 –

+0

另請參閱[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-erlang-guard),[this](http:// stackoverflow。/功能/不能使用功能調用保護)和[this](http://stackoverflow.com/questions/7474894/use-of-function-in-guard-not -allowed-suggestions-for-alternate-implementation-w)問題。 – legoscia

回答

9

您不允許在警衛中使用用戶定義的功能。這是因爲警衛的職能必須避免副作用(例如在您的職能中使用io:format)。在守衛,你只限於以下內容:

  • 用於型式試驗(is_atomis_constantis_floatis_integeris_listis_numberis_pidis_portis_referenceis_tupleis_binaryis_functionis_record
  • 的BIF
  • 布爾操作符(notandorandalsoorelse,;),
  • 關係運算符(>>=<=<=:====/=/=),
  • 算術運算符(+-*divrem),
  • 位運算符(bandborbxorbnotbsl, bsr),
  • 其他BIF tha t爲無副作用(abs/1element/2hd/1length/1node/1,2round/1size/1tl/1trunc/1self/0
+4

嗯,似乎檢查副作用將是一個非常簡單的靜態分析技巧... –

+5

@MartinKristiansen不是真的,因爲模塊中的任何代碼都可以在運行時更改或替換。 –

+0

@alexeyRomanov:你是絕對正確的 - 但也許然後限制使用BIF的和當前模塊內的功能:-) –

5

另一個原因不允許在警衛用戶定義的函數是錯誤在不同的處理警衛而不是「正常」的功能。在警衛中,不是產生異常,它只會導致警衛本身失敗。

衛兵不是真的表情,而是測試

相關問題