以下REPL片段假定:
import scala.util.{Try, Success, Failure}
为什么这两个语句没有通过编译?我得到"构造函数无法实例化为期望的类型":
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"; }
我可以使用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"; }
答案 0 :(得分:19)
考虑一下:
Try(1) match {
case Success(i) => i
case Failure(t) => 0 // t is the `Throwable`
}
这是有效的,因为Success
和Failure
是抽象类Try
的子类。但是,以下代码无法编译,因为您不再匹配通用Try
,而是Failure
永远不会成为{的实例{1}}。
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"
}
与Integer
匹配一样,但它确实没有意义。
如果您希望通过模式匹配获得String
,请参阅第一段代码。
您可以提取Throwable
的另一种方法是在Throwable
上使用failed
方法,这会将Try
包裹在Throwable
内的失败中}。
Success
然而,在scala> val t: Throwable = Try(throw new Exception).failed.get
t: Throwable = java.lang.Exception
上调用它会引发另一个异常。
答案 1 :(得分:11)
第一个代码段无法编译,因为Success
不是Failure
的子类型。编译器认为你很愚蠢,因为Success(i)
案例永远不会匹配。
举一个更简单的例子,这也没有编译。
Failure(new Exception()) match { case Success(_) => }
出于同样的原因,这也不是。
42 match { case Success(_) => }
你所写的内容几乎可以正常运作,但你匹配的价值必须有一个更通用的Try[_]
类型(无论如何,如果模式匹配实际上是用于一些有用的上下文)。
(Failure(new Exception("a")): Try[_]) match {
case Success(i) => "a"; case Failure(e) => "b"; case _ => "c"; }