我很好奇为什么scala.util.Try
没有像
abstract class Try[+E <: Throwable, +T] {
recoverWith[U >: T](f: PartialFunction[E, Try[E, U]]): Try[E, U]
...
}
对文档有帮助,例如
def parseInt(s: String): Try[NumberFormatException, Int]
仍然无法表达像throws SecurityException, IllegalArgumentException
这样的不相交的异常类型,但至少朝这个方向迈出了一步。
答案 0 :(得分:2)
这可能就是你要找的东西:
import scala.util.control.Exception._
import scala.util.{ Success, Failure }
def foo(x: Int): Int = x match {
case 0 => 3
case 1 => throw new NumberFormatException
case _ => throw new NullPointerException
}
val Success(3) = catching(classOf[NumberFormatException]).withTry(foo(0))
val Failure(_: NumberFormatException) = catching(classOf[NumberFormatException]).withTry(foo(1))
// val neverReturns = catching(classOf[NumberFormatException]).withTry(foo(2))
请参阅scala.util.control.Exception$
然而,没有办法将Try[T]
专门化为假设的Try[ExcType, T]
;为了使其工作,你需要像Either
这样的东西(但可能更复杂一些,如scalaz.\/
,或者,对于超过1个异常类,Shapeless'Coproduct
):< / p>
def bar(x: Int): Either[NumberFormatException, Int] = {
catching(classOf[NumberFormatException]).withTry(foo(x)) match {
case Success(x) => Right(x)
case Failure(exc) => Left(exc.asInstanceOf[NumberFormatException])
}
}
println(bar(0)) // Right(3)
println(bar(1)) // Left(java.lang.NumberFormatException)
// println(bar(2)) // throws NullPointerException
应该可以将其概括为适用于任意数量的异常类型的通用帮助程序。在这种情况下,你肯定必须使用Shapeless'Coproduct
和facilities for abstracting over arity。不幸的是,这是一项非常重要的练习,我现在没有时间为你实现这一点。