2011-11-11 12 views
10

初期化するコードが例外をスローする可能性があるvalのセットを初期化する必要があります。例外をスローする可能性のある初期化の値

xとyがtryの範囲外にあるので、これは(明らかに)動作しません。

それは可変変数を使用して問題を解決するのは簡単です:

var x: Whatever = _ 
var y: Whatever = _ 
try { 
    x = ... generate x value ... 
    y = ... generate y value ... 
} catch { ... exception handling ... } 

... use x and y ... 

しかし、それは正確に非常に良いではありません。

それは例外処理を複製することによって、問題を解決することも簡単です。

val x = try { ... generate x value ... } catch { ... exception handling ... } 
val y = try { ... generate y value ... } catch { ... exception handling ... } 

... use x and y ... 

しかし、それは例外処理を複製すること。

「すばらしい」方法が必要ですが、それは私を逃しています。

+1

初期化中に例外がスローされた場合、遅延ロードは次のアクセス時にその値を再計算する可能性がありますか? – soc

答えて

5

簡単な解決策は、by-nameパラメータを使用するラッパー関数を定義することです。

Scala 2.9では、例外的なハンドラとして使用することができます。

val handler: PartialFunction[Throwable, Unit] = { /* exception handling */ } 
val x = try { generateX } catch handler 
val y = try { generateY } catch handler 

全体として、私は最初の方法が最も簡単だと言います。しかし、orElseまたはandThenを使用して一緒に構成できる例外ハンドラの再利用可能なビットを書くことができる場合は、2番目の方法が適切です。

9

パターンマッチングはどうですか?あなただけのスローだ任意の例外をキャッチしてcatchブロックで手続き何かをしたい場合は

val (x, y) = try generateX -> generateY catch { /*exception handling*/ } 

または

val (x, y) = try (generateX, generateY) catch { /*exception handling*/ } 
+0

「Some」は必要ありません。 –

+0

Thx、修正済み... – agilesteel

+2

これは複数の回答を受け入れることができるようにしたいという状況の1つです。私は使用し終わったものに最も近いので、私はdaveの答えを受け入れましたが、これらのすべてが良いアプローチです。ありがとう! –

7

agilesteelの答えは結構です。ただし、後で個々に例外を処理することができます。その場合は、タイプをOptionまたはEitherにすることを検討することがあります。

組み込みの方法は、Catchオブジェクトです。 Exception docsを参照してください。

どのように使用するかは、例外が発生したときにどうしたいかによって異なります。例えば

import util.control.Exception.allCatch 

def handleInfinities(n: Int) = { 
    val x = allCatch.either { 100/n }  // Either[Throwable, Int] 
    val y = allCatch.either { 100/(n - 1) } 

    Seq(x, y) map { case Left(_) => Int.MaxValue; case Right(z) => z } 
} 

その後handleInfinities(1)は、変数の代入と例外の取り扱いは今完全に分離されていますか

Seq[Int] = List(100, 2147483647) 

通知します。

+0

これは複数の回答を受け入れることができるようにしたいという状況の1つです。私は使用し終わったものに最も近いので、私はdaveの答えを受け入れましたが、これらのすべてが良いアプローチです。ありがとう! –

1
import util.control.Exception._ 
def handler[A]: Catch[A] = handling(classOf[Exception]) by exceptionHandlingFunc 
val x = handler[X] apply { generateX } 
val y = handler[Y] apply { generateY } 
関連する問題