4

重複の可能性:
scalaでの「return」および「try-catch-finally」ブロック評価

2つのScala関数があります:

a):def foo(): Int = try { 1 } finally { 2 }

b):def bar(): Int = try { return 1 } finally { return 2}

なぜfoo1をbar返すのか、2を返すのかわかりません。

4

2 に答える 2

11

この動作は、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の例を参照してください

于 2012-12-15T14:51:52.240 に答える
1

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

}
于 2012-12-15T14:50:09.957 に答える