2016-11-13 12 views
1

これは非常に基本的な質問ですが、どこでも答えを見つけることはできません。戻り値のないScalaメソッドでは、メソッドを途中で終了するにはどうすればよいですか? Javaでのようなreturnを使用しようとすると、例えば Scalaでvoidメソッドを中断または終了する方法はありますか?

def printPositiveNumbersSum (n1: Int, n2: Int) = { 
    if (n1 < 0 || n2 < 0) 
     // How do I break out of this method here? 
    println(n1 + n2) 
} 

printPositiveNumbersSumは、戻り値の型を持っていないというエラーが発生します。

私はこれをif-elseステートメントにすることができますが、メソッドを終了して呼び出し元に戻る条件が複数ある場合は、すぐに扱いにくくなります。

答えて

1

基本的な質問には、見た目よりも面白い習慣があります。これにアプローチするには、代替案として検討する価値がある2つの方法があります。しかし、基礎は、すべてが特定の型の値を返すことであり、コンパイラはその型が何であるか把握しようとします。あなたのケースでは、printPostiveNumbersSumはある種のものを返します。

  • あなたのメソッドがユニットを返すようにします。タイプUnitは、機能または実行可能コードの一部を意味します。この回答はすでに述べられています。
  • 合計のオプション[Int]を返すことを検討してください。検証が成功した場合はSome(sum)を返し、失敗した場合はNoneを返します。呼び出し元は、おそらくmatch { case Some(sum)...構造を使用して、失敗の場合に何をすべきかを決定できます。

    def positiveNumbersSum (n1: Int, n2: Int): Option[Int] = { 
        if (n1 < 0 || n2 < 0) 
        None 
        else Some(n1 + n2) 
    } 
    
  • しかし、より複雑な例で

    、あなたが考慮すべき複数のルールを有することができるとき、失敗ではなく、単にNoneを返すため理由を返すことが便利です。この場合、Eitherが便利です。あなたは2つの戻り値の型を指定します。ここでも、呼び出し側はmatch { case Left(reason)... case Right(sum)...構成で区別できます。

    def positiveNumbersSum (n1: Int, n2: Int): Either[String,Int] = { 
        if (n1 < 0 || n2 < 0) 
        Left("One of the numbers is negative") 
        else Right(n1 + n2) 
    } 
    
3

あなたはあなたの方法

def printPositiveNumbersSum(n1: Int, n2: Int): Unit = { 
    if (n1 < 0 || n2 < 0) 
     return 
    println(n1 + n2) 
    } 

からユニットの戻り値の型を指定する必要があり、それはその後、幸せなScalaのコンパイラを保持します。

1

ロジックを反転し、returnキーワードを使用する必要がなくなります。あなた自身がこの問題に実行して見つけた場合

def printPositiveNumbersSum (n1: Int, n2: Int) = { 
    if (n1 >= 0 && n2 >= 0) 
    println(n1 + n2) 
} 

あなたは、メソッドに複数の出口ポイントを持つべきではない、あなたはあなたのソリューションを再評価する必要があります。

また、scalaのreturnキーワードは直感的ではありません。 returnキーワードはこれで何をするつもりされて正確に何

def printMany(l: List[(Int, Int)]): Unit = 
    l.foreach { case (n1, n2) => 
     if (n1 < 0 || n2 < 0) return 
     println(n1 + n2) 
    } 

:あなたはIntペアのリストを持っていた、そしてあなたは、リストを反復処理したい場合は、すべてのpoisitiveペアを印刷し、あなたはそうのような関数を書くかもしれませんシナリオ?リストval l = List((1,1), (2,2), (-1, 2), (5,4))があれば、2、4を印刷して停止します。 returnキーワードは、ネストされたラムダではなくメソッド全体から戻されます。

このため、ほとんどの場合、スカラでのリターンの使用は避けることをお勧めします。

+3

http://softwareengineering.stackexchange.com/questions/118703/where-did-the-notion-of-one-return-only「あなたはメソッドに複数の出口ポイントを持つべきではありません」 -から来る –

関連する問題