为多个异常返回相同的值

时间:2013-12-26 19:43:21

标签: scala

给定一个捕获多个异常的块,是否可以处理多个异常而不在每个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}中设置默认值 - 但这看起来像代码味道所以我希望有一个更优雅的解决方案。

4 个答案:

答案 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 }