将失败的未来的异常映射到 Some,但 isDefined 不起作用

Map the exception of a failed future to Some, but isDefined does not work

刚遇到一个scala的奇怪问题。我将未来失败的异常映射到 Some 类型,但 isDefined 函数不适用于 Some 变量。代码仅供测试:

val c =  Future.failed(Error("divide 0 !!!!!"))
val d = c.map(Some(_))
val e = d.map { v => if (v.isDefined) println("Got some!!!!")}  

d 是 scala.concurrent.Future[Some[Nothing]] 的类型,但是,e 不能打印 "Got some!!!!",这意味着它认为 d 不是 Some 类型,但它是。我错过了什么吗?感谢您的帮助。

map() 函数仅在 Future 执行成功时应用,但不适用错误情况。有多种选择可以解决您的问题。第一个但不是很好的是明确表示 Future 的结果包含一个异常:

val c =  Future.failed(Error("divide 0 !!!!!"))
val d = c.failed.map(Some(_))
d.foreach { v => if (v.isDefined) println("Got some!!!!")}

但此解决方案仅在您确定 Future 包含异常时才有效,这通常表明您的代码中存在严重的设计缺陷。

另一种解决方案是使用 transform(),它还允许您访问错误案例并将其转换为您想要的特定值:

val c =  Future.failed(Error("divide 0 !!!!!"))
val d = c.transform {
   case Success(value) => Success(Some(value))
   case Failure(error) => Success(Some(error))
}
d.foreach { v => if (v.isDefined) println("Got some!!!!")}

处理这些情况最常用的函数是recover()函数。这明确表示用于对错误情况做出反应并将它们转换为某种形式的结果对象:

val c =  Future.failed(Error("divide 0 !!!!!"))
val d = c.map(Some(_)).recover {
   case error:Error => Some(error)
}
d.foreach { v => if (v.isDefined) println("Got some!!!!")}

c.map(Some(_))只会转化所有成功案例。使用 recover(),您将对所有 Error 类型的 Throwable 做出反应,并将它们也转换为 Some。对于此特定情况,所有其他 Throwable 仍将被忽略。

我希望这能帮助您继续学习 ;-)