2016-12-09 6 views
0

Scalaでの例外処理に関する記事を読んでいましたが、このコードスニペットはthisブログに出ました。例外処理中のスカラクロージャの動作

def containsEven(nums: String*): Boolean = { 
    try { 
     for (i <- nums) { 
     if (i.toInt % 2 == 0) 
      return true 
     } 
    } catch { case e =>() } 
    false 
    } 

このコードは関係なく、常に入力の出力としてを返します。これはブログ上での説明です。

上記の実装から、我々はcontainsEven( "1"、 "3")はfalseを返すとcontainsEvenは( "2"、 "3")真 を返す必要があることをすべきであることを期待します。残念ながら、これは当てはまりません。入力に関係なく、 メソッドは常にfalseを返します。これは、キャッチブロックで は、式ケースe => でThrowableをキャッチするパターンを使用していたためです。より長いがより正確なパターンの場合は、e: NumberFormatException => ... NumberFormatExceptionのみがキャッチされます。 これがバグの原因である理由を理解するために、 Scalaがクロージャからの非ローカル戻りを実装する方法を理解してください。

あり、より説明がナイーブScalaのプログラマーとして、私は消化できなかった

非局所的なリターン

に関連します。

このように、単純な言葉でクロージャの問題点を理解できるように助けてもらえますか?

答えて

2

実際には文がスローされます。つまり、次の実行行はローカルではない可能性があります。 case eは無差別であるため、すべてのスローアブルをキャッチします。今度はtrycatchの両方が完了したので、実行は次の行、falseに続き、その値でdefを終了します。

これを適切な場所に置き、さまざまな入力情報を確認します。

catch { case e => println(s"caught:$e");() } 

これは全く異なる結果をもたらします。

catch { case e: NumberFormatException => println(s"caught:$e");() } 
+0

私が提案した変更に同意します。なぜこのように振る舞っているのかを理解するために 'catch {case e =>' –