2

最初の質問: アロー アンチ パターンは Scala で物事を行う方法ですか?

Java から Scala に移行してから約 3 か月が経ちました。アンチ アロー パターンが Scala の標準になっていることがわかり始めています。

たとえば、Java では、できるだけ早くメソッドから戻るのが好きです。私たちは多くの内側の入れ子が好きではありません。それらがたくさんある場合、それはアロー アンチ パターンと呼ばれます。ここでそれについて読むことができます: http://c2.com/cgi/wiki?ArrowAntiPattern

Java の例:

boolean isValid(String input){
  if (input.trim().length() <1) return false //return early
  if (input.substring(0,3).equals("sth")) return false;

  //do some more checks for validity then return true

  return true
}

これを Scala で記述した場合、多くのインデントが発生する match-case ステートメントを使用する必要があります。これは、Scala の入れ子とインデントのみを伝えようとするダミーの例にすぎないことに注意してください。

def isValid(input:String):  Boolean = {
  (input.trim.length < 1) match {
    case true => 
      input.substring(0,3) match {
        case sthCase if(sthCase=="sth") =>
          //do some more checks etc

          //eventually arrive at the "true" branch
               ... case valid => true

        case sthElse if (sthCase=="bla") => //some more code etc
        case _ => false
      }
    case _ => false
  }
}

この例は、Java の例と同じように記述できることはわかっていますが、true または false を返す代わりに、その値を変数に代入したい場合、つまりval valid = (input.trim.length < 1) match ...、これが唯一の方法です。 val に再割り当てします。varの代わりに使用することもできますvalが、Scala の代わりに Java を使用することになります。

質問、繰り返し: 質問は、矢印のアンチ パターンは Scala で何かを行う方法なのか、それとも何か不足しているのかということです。私が今書いたことを Scala で行うためのより良い方法はありますか (match ステートメントの結果をval変数に割り当てたいことに注意してください)。

4

4 に答える 4

4

コードのすべての部分が単一のエントリ/単一の出口である限り、Scala ではいつでも分解を使用できることに注意してください。これが機能するのは、Scala のネストされた関数が外側の関数のローカル変数にアクセスできるためです。例えば:

def isValid(input: String): Boolean = {
  def testLength = input.trim.length >= 1
  def testSomething = input.substring(0, 3) == "sth"

  return testLength && testSomething
}

したがって、矢印のような構造を必要なだけサブコンポーネントに分解できます。

また、ブール値のテストや等価性の比較に match を使用するのはやり過ぎであることに注意してください。

于 2013-06-05T15:45:41.437 に答える
3

関数に sが多すぎる場合return、関数が欠落しています。

def isValid(s: String): Boolean = {
  def isLengthValid = s.trim().length() > 0
  def shouldNotContainsSomething = s.substring(0, 3) != "sth"

  isLengthValid && shouldNotContainsSomething
}
于 2013-06-05T15:47:01.833 に答える
3

if/elseあなたの Java の例は、明示的なリターンやネストの追加レベルなしで、簡単に in scala に変換できます。

def isValid(input: String) = {
  if (input.trim().length() <1) false
  else if (input.substring(0,3).equals("sth")) false
  else true
}

if/else同様に、scala のすべてが式であり、戻り値があるため、割り当てに使用することもできます。

val isValid =
  if (input.trim().length() <1) false
  else if (input.substring(0,3).equals("sth")) false
  else true

または、この場合、単に書くこともできます

val isValid = (input.trim().length() >= 1) && (!input.substring(0,3).equals("sth"))
于 2013-06-05T15:06:43.870 に答える
2

あるルールがそう言っているという理由だけでカーゴカルトをしないでください。Scala の良いところは、両方の世界から最善を尽くすことができることです。たとえば、可変スタイルで記述されたアルゴリズムは、不変スタイルよりもはるかに明確な場合があります。

ちなみに、requirefail on validation でよく使われるメソッドもあります(ただし、例外で上がります)。

于 2013-06-05T15:09:06.817 に答える