2011-11-11 37 views
10

我需要初始化一组val,初始化它们的代码可能会抛出异常。我很想写:初始化可能抛出异常的值

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

... use x and y ... 

但是这(显然)不起作用,因为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

也许你利用延迟vals在下一次访问时重新计算它们的值的事实,如果在初始化过程中引发异常? – 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 

总的来说,我会说第一种方法是最直接的。但是如果你可以编写可重复使用的异常处理程序,可以使用orElseandThen来组合,那么第二种方法会更合适。

9

模式匹配怎么样?

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

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

你不需要'Some'。 –

+0

Thx,固定它... – agilesteel

+2

这是我希望允许多个答案被接受的情况之一。我已经接受戴夫的答案,因为它最接近我最终使用的,但所有这些都是很好的方法。谢谢! –

7

agilesteel的回答是好的,如果你只是想赶上那真实抛出的任何异常,并做一些在catch块程序。但是,您可能希望稍后单独处理例外情况,在这种情况下,您可以考虑将类型设为OptionEither

内置的方法是使用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
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 } 
相关问题