2つのScala関数があります:
a):def foo(): Int = try { 1 } finally { 2 }
b):def bar(): Int = try { return 1 } finally { return 2}
なぜfoo
1をbar
返すのか、2を返すのかわかりません。
2つのScala関数があります:
a):def foo(): Int = try { 1 } finally { 2 }
b):def bar(): Int = try { return 1 } finally { return 2}
なぜfoo
1をbar
返すのか、2を返すのかわかりません。
この動作は、M.Odersky、L。Spoon、B.Vennersによる「ProgramminginScala」で説明されています。私は初版を持っており、セクション7.5(128ページ)には次のように書かれています。
Scalaの動作がJavaと異なるのは、Javaの動作が
try-finally
値をもたらさないという理由だけであることに注意してください。Javaの場合と同様に、finally
句に明示的なreturnステートメントが含まれている場合、または例外がスローされた場合、その戻り値または例外は、tryブロックまたはそのcatch句の1つで発生した以前のものを「無効」にします。たとえば、次のようになります。
def f(): Int = try { return 1 } finally { return 2 }
f()を呼び出すと2になります。対照的に、次のようになります。
def g(): Int = try { 1 } finally { 2 }
g()を呼び出すと1になります。これらの関数はどちらも、ほとんどのプログラマーを驚かせる可能性のある動作を示します。したがって、通常、
finally
句から値を返さないようにするのが最善です。
Scala標準ライブラリにはscala.util.control.Exception
、例外を処理するための小さな機能ライブラリを提供するAPIがあります。scaladocの例を参照してください
bar()のfinallyブロックのreturnステートメントは、メソッドbar()を終了します。そのため、tryブロックの結果は返されません。
この例は、(ほぼ)同等のバージョンのfoo()メソッドとbar()メソッドを示しています。
object Test extends App {
def foo() = {
val result = { 1 }
{ 2 }
result
}
def bar(): Int = {
val result = { 1 }
{ return 2 }
result // this line is not processed
}
println("foo = " + foo()) // foo = 1
println("bar = " + bar()) // bar = 2
}