10

私はウェブ上でこのコードに出くわしました:

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.

これは、入力が文字列であるかどうかをチェックするという点で、私が常に夢見ていたGuardです。ただし、erlangでの使用は許可されていません。これはなぜですか?そして、回避策はありますか?

私は次のようなものを書けるようになりたいです:

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

または、メッセージに使用することをお勧めします。

4

2 に答える 2

12

ガードでユーザー定義関数を使用することは許可されていません。これは、ガード内の関数に副作用(io:format関数での使用など)がないようにする必要があるためです。警備員では、次のように制限されています。

  • タイプテストに使用されるBIF (、、、、、、、、、、、、、、、)is_atom、_ _ _is_constantis_floatis_integeris_listis_numberis_pidis_portis_referenceis_tupleis_binaryis_functionis_record
  • ブール演算子(、、、、、、、、)notand_ or_andalsoorelse,;
  • 関係演算子(、、、、、、、、、)>>=_ <_ =<_=:====/=/=
  • 算術演算子(、、、、、)+-*divrem
  • ビット演算子(、、、、、、)bandborbxorbnotbslbsr
  • 副作用のない他abs/1のBIF (、、、、、、、、、、、)_ _element/2hd/1length/1node/1,2round/1size/1tl/1trunc/1self/0
于 2012-06-24T11:54:13.737 に答える
5

ガードでユーザー定義関数を許可しないもう1つの理由は、ガードでは「通常の」関数とは異なる方法でエラーが処理されるためです。ガードでは、エラーによって例外が生成されることはなく、ガード自体が失敗するだけです。

ガードは実際には表現ではなく、テストです。

于 2012-06-27T01:22:09.140 に答える