scala.util.Try:如何获得Throwable值?模式匹配?

cla*_*lay 9 scala try-catch

以下REPL片段假定:

import scala.util.{Try, Success, Failure}
Run Code Online (Sandbox Code Playgroud)

为什么这两个语句没有通过编译?我得到"构造函数无法实例化为期望的类型":

Failure(new Exception("a")) match {
  case Success(i) => "a"; case Failure(e) => "b"; case _ => "c"; }

Success(123) match {
  case Success(i) => "a"; case Failure(e) => "b"; case _ => "c"; }
Run Code Online (Sandbox Code Playgroud)

我可以Try通过get或获得成功价值toOption.有没有相应的方法来获得失败的Throwable价值或Option[Throwable]

编辑:从失败/成功投射尝试工作

Failure(new Exception("a")).asInstanceOf[Try[Int]] match {
  case Success(i) => "a"; case Failure(e) => "b"; case _ => "c"; }

Success(123).asInstanceOf[Try[Int]] match {
  case Success(i) => "a"; case Failure(e) => "b"; case _ => "c"; }
Run Code Online (Sandbox Code Playgroud)

Mic*_*jac 19

考虑一下:

Try(1) match {
    case Success(i) => i
    case Failure(t) => 0 // t is the `Throwable`
}
Run Code Online (Sandbox Code Playgroud)

这是因为SuccessFailure是抽象类的子类Try.但是,下面的代码编译失败,因为你不再匹配上一个通用的Try,而是一个Failure可以永远是一个实例Success.

Failure(new Exception("a")) match {
    case Success(i) => "a" // You can see it compiles if you remove this line.
    case Failure(e) => "b"
    case _ => "c"
}
Run Code Online (Sandbox Code Playgroud)

这就像尝试匹配Integera String,它没有真正意义.

如果要获取Throwablevia模式匹配,请参阅第一段代码.

你可以提取的另一种方法Throwable是使用failed你的方法Try,它将包装Throwable失败Success.

scala> val t: Throwable = Try(throw new Exception).failed.get
t: Throwable = java.lang.Exception
Run Code Online (Sandbox Code Playgroud)

Success但是,在a上调用它会抛出另一个异常.


Chr*_*tin 11

第一个片段无法编译,因为Success它不是子类型Failure.编译器认为你很傻,因为Success(i)案件永远不会匹配.

举一个更简单的例子,这也不能编译.

Failure(new Exception()) match { case Success(_) => }
Run Code Online (Sandbox Code Playgroud)

出于同样的原因,这也不是这样.

42 match { case Success(_) => }
Run Code Online (Sandbox Code Playgroud)

你所编写的内容几乎可以正常工作,但是你匹配的值必须具有更通用的类型Try[_](无论如何,如果模式匹配实际上在某些有用的上下文中使用,它将具有它).

(Failure(new Exception("a")): Try[_]) match {
    case Success(i) => "a"; case Failure(e) => "b"; case _ => "c"; }
Run Code Online (Sandbox Code Playgroud)