给定一个捕获多个异常的块,是否可以处理多个异常而不在每个case
块中放置所需的值?例如如果像这样的东西工作会很好:
val foo: Int = try {
//do stuff that results in an Int
} catch {
case e: SomeException => //do something if this gets thrown
case e: SomeOtherException => //do something different if this gets thrown
0
}
但是这会导致编译错误(type mismatch; found : Unit required: Int
)。我可以在每个throwable case e: SomeException => {/*do something if this gets thrown*/; 0}
中设置默认值 - 但这看起来像代码味道所以我希望有一个更优雅的解决方案。
答案 0 :(得分:4)
您可以利用部分功能使用内置的Try
val foo: Int ={
val value = Try{
//stuff
}
unwrap(0, value){
case x: SomeException => doStuff()
case x: OtherExcetion => doMoreStuff()
}
}
def unwrap[A](ret: A, value: Try[A])(f: Failure[A] => Unit): A = value match{
case Success(x) => x
case x: Failure => f(x); ret
}
瞧,瞧,你处理得很好。
答案 1 :(得分:4)
您可以简单地包装异常处理:
val foo: Int = try {
//do stuff that results in an Int
17
} catch { case t: Throwable => t match {
case e: SomeException => //do something if this gets thrown
case e: SomeOtherException => //do something different if this gets thrown
}
42
}
答案 2 :(得分:1)
catch
关键字需要PartialFunction
,可以轻松与andThen
链接:
scala> val pf1: PartialFunction[Throwable, Unit] = { case _: IllegalArgumentException => println("pf1") }
pf1: PartialFunction[Throwable,Unit] = <function1>
scala> val pf2: PartialFunction[Unit, Int] = { case _ => println("pf2"); 0}
pf2: PartialFunction[Unit,Int] = <function1>
scala> try throw new IllegalArgumentException catch pf1 andThen pf2
pf1
pf2
res0: Int = 0
scala> try throw new NoSuchElementException catch pf1 andThen pf2
java.util.NoSuchElementException
第二个PartialFunction
仅在第一个匹配其参数时执行,当您想要捕获其他异常(也不应返回默认值)时,这可能是一个问题。但对于这种情况,有orElse
:
scala> val pf3: PartialFunction[Throwable, Int] = { case _ => println("pf3"); 1}
pf3: PartialFunction[Throwable,Int] = <function1>
scala> try throw new NoSuchElementException catch pf1 andThen pf2 orElse pf3
pf3
res2: Int = 1
答案 3 :(得分:0)
您可以使用Try对象来包装可能失败的代码,然后像这样编写结果
val foo: Int = (Try {
//do stuff that results in an Int
} recover {
//here we handle the recovering
handleFail andThen defaultInt
}).get
val handleFail: PartialFunction[Throwable, Unit] = {
case e: SomeException => //do something if this gets thrown
case e: SomeOtherException => //do something different if this gets thrown
val defaultInt: PartialFunction[Unit, Int] = { case _ => 0 }