2011-12-09 5 views
14

で "のtry-catch-最後に" ブロックの評価次の2つのコードは、異なる結果を生成します。"リターン" とScalaの

def x = try{ 
    true 
} finally false 

ボークxがyがfalse

を取得 true

def y:Boolean = try{ 
    return true 
} finally { 
    return false 
} 

呼び出しを取得します

returnのバージョンはJavaと同じです。

個人的に私は決してスカラで「リターン」を使用しません。しかし、try-catch-finallyブロックの値をスカラーがどのように評価するかを知ることは良いことです。ありがとう。

答えて

13

should notはfinallyブロック内にreturn文を持っています(少なくともJavaでは技術的に許可されていますが、C#では禁止されています)。

Scala finallyブロックが暗黙のリターンを持っていた場合、それは常に意図したリターン値を壊します。それは意味をなさない。

しかし、あなたが明示的にそれを書いておけばそれはあなたを助けることができないと思います。

+0

しかし、「暗黙の復帰」とは何ですか? – xiefei

+0

"暗黙の復帰":間違った単語かもしれませんが、私が意図したことは、コードブロックの最後の行の結果をブロックの戻り値として使用することです。 – Thilo

+2

Thiloが正しいです。 'finally'ブロックに' return'ステートメントを置くことは間違いとみなされ、実際には許されません。 'Finally'は、メソッド本体が成功するか例外をスローするかに関係なく、要素をクリーンアップすることです。それは戻り値を決める場所ではありません!したがって、 'finally'節の本体は' Unit'と評価されます。あなたの最初の例では、 'false'は暗黙的に' Unit'に変換されます。 –

9

Scalaの言語仕様によると:{B}最後にeはブロックBを評価

トライ発現試して。 b の評価で例外がスローされない場合、式eが評価されます。 eの評価中に例外 がスローされた場合、try式の評価はスローされた例外を伴う を打ち切ります。 eの評価中に例外がスローされない場合は、try式の結果として の結果が返されます。

この動作は、この仕様と矛盾しているようです。私は、 'return'はファンクションからの即時復帰を引き起こすので、tryブロックの標準動作をオーバーライドすることになります。照明の例は次のとおりz戻りfalseを呼び出す

def z : Boolean = { 
    val foo = try { true } finally { return false } 
    true 
} 

+3

はい、finallyブロックから戻ってフロー制御を中断します。それは禁止されるべきです。 – Thilo

+11

'return'は常にフロー制御を中断します。その場合、それは特に奇妙にしかなりません。 – Debilski

+0

仕様通りです。次の段落では、 'e'の型は' Unit'に従うと期待されています。つまり、 'e'は副作用だけが評価されます。 'e'が' return .. 'のとき'の場合、評価ルールは制御フローが現在実行されているメソッドを離れ、与えられた引数を返すと言う。 –