2009-06-26 15 views
18

私は今、かなりのErlangコードを書いた段階に入っています。私が行ったようなスタイルに(悪いものも良いものも)それを書く。この特定のイディオムについて私はいくつかの意見をお伝えしたいと思いますが、大文字と小文字のスタイルステートメントを機能パターンマッチングに変換するほうが、読みやすく(より速く/何でも)良いのですか?Erlangスタイル - ケース対関数パターンマッチング

など。

... 
maybeChangeStorage(Size, Type) 
... 

maybeChangeStorage(Size, ets) when Size > 10000 -> 
    something; 
maybeChangeStorage(Size, dets) when Size < 10000 -> 
    somethingelse; 
maybeChangeStorage(_,_) -> 
    ignoreit. 

(不自然な例)を比較

case {Size > 100000, Type} of 
    {true, ets } -> 
     %% Do something to convert to dets 
     something; 
    {false, dets} -> 
     %% do something to convert to ets 
     somethingelse; 
    _ -> 
     ignoreit 
end; 

私は、ほとんどの場合、後者を好むが、私は他の意見に興味があると思います。

+0

maybeChangeStorage(Size、dets)サイズが< 10000 ->の場合はサイズ<= 10000 – JLarky

答えて

11

秒あなたは、単一の行に句を保つことができる場合は特に好ましい方法である:

maybeCngStor(Sz, ets) when Sz > 10000 -> something; 
maybeCngStor(Sz, dets) when Sz < 10000 -> somethingelse; 
maybeCngStor(_,_)      -> ignoreit. 

約それは非常に読みやすいとの理由にします。常に読むのが最も簡単なスタイルを選択してください。それらを整列する条項をレイアウトし、短い使用などの

maybeCngStor(Sz, ets) when Sz > 10000 -> something; 
maybeCngStor(Sz, dets) when Sz < 10000 -> somethingelse(); 
maybeCngStor(_,_)      -> ignoreit. 

somethingelse() -> 
    (...) 
    Return. 

ささいなこと:関数に長いものを破る - 多くの場合、あなたは1つが10ライナーと残りは唯一のラインである節の集合を見つけます変数名は関係 - あなたが使用している場合は多くのことを記録し良いトリック

が、P、Qにすべてを変えるの罠に分類されない、R.

短い変数にレコードを一致させることです。

#record{foo = F, bar = B, baz = Bz} = Parameter 

これは、あなたがパラシュートの時に意味を持つ短い変数名を与えますeを10,000フィートの関数から次のクリスマスのバグを探して探しています。 Fは明らかに私はいくつかの変更を行ったときに私が見つけたのFoo、などなど...

+2

私はほとんどの場合、機能が一致するのが本当に好きです。私のためのサイクルは、通常、次のようなものになります。後で機能にリファクタリングする。私はその後、リファクタリングの後に大きくコードを書く傾向があります。私はそれを1行に近づけるほど、私はより幸せに機能します。 –

0

私の場合、ファーストスタイルはもっと明確で速いかもしれません。しかし、正確に言うにはテストが必要です。 2番目のケースでは!= etsと入力すると、「Size> 10000」と「Size < 10000」の両方が評価されます。

+0

はい、ロジックから少し離れている可能性があるので、メモリからフラグメントを書きました。私が最初のスタイルについて気に入ったことの1つは、パターンマッチングを行うタプルの魔法の構築でした。私は{Test1、Test2、Test3、Test4}のようなものを使っていましたが、私が実際に興味を持っていた特定の組み合わせのために、それはネストされたif文の全セットを打ち負かしました! –

+1

変数のサイズをテストするコストがマイクロ最適化であることを心配してください。可能な限り明確なコードを書いてください。テストに基づいて、この構造のこの特定のインスタンスが遅すぎるという兆候がある場合は、それを変更してください。 –

3

あなたは行って、これらの例は、より近づけることができます。

case Type of 
    ets when Size > 10000 -> ...; 
    dets when Size < 10000 -> ...; 
    _ -> ... 
end. 

これは私に明確であるように思われます。これを別の関数に分割する利点は、ドキュメントとして機能し、スタックトレースに現れる名前を与えることです。そのスニペットがより大きい関数の一部であるなら、私はそれを分けたいでしょう。さもなければそれは大丈夫です。

考慮すべき点の1つは、関数が記述したエラーの場合、ets/dets以外のType引数を受け入れることです。これが本当に必要でない限り、この節をより限定的にする価値があります。

+2

_をcatch all句として使用すると、いつも私にも悪い匂いがします。私は通常、それを除外して、パターンマッチングがそれを投げ捨てるようにします。しかし、この特定のケースでは、一致しない場合は何もしませんでした。 私は、ケース節にガードを置く別のアプローチが好きです。 –

0

は(コードの書式設定を取得するための答えとして入れて...!)

一つのことですこのアプローチがデフォルトの短絡を変更する可能性があるのは です。例えば。

case A > 10 of 
     true -> 
      case B > 10 of 
        true -> dummy1; 
        false -> dummy2 
      end; 
     false -> dummy3 
end 

は時々何をしたい

doTest(true, true) -> dummy1; 
doTest(true, false) -> dummy2; 
doTest(false, _) -> dummy3. 

をされていないときに

doTest(A > 10, B > 10) 

のようにそれを呼び出した場合、常に> 10 Bを実行する必要があります!

0

あなたの関数で最初に行うのはcase節を開いている場合、この最上位レベルの節を関数パターンマッチングに変換する方がよいでしょう。

3

Learn you some Erlang for great goodは、caseをいつ選択し、いつfunctionを使用するかについては、small sectionがあります。二つのものが挙げられる:2つのソリューションの性能に差がないので、

  1. 彼らはVMで同じことを表現しています。

  2. 複数の引数に対してガードを使用する必要がある場合は、関数を使用すると読み込まれやすくなります。

おそらく、おそらくスタイルと味の問題です。

関連する問題