从异常中恢复,scala未来

从异常中恢复,scala未来,scala,Scala,为什么scala代码要编译, recover的签名是 def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] 那么下面的代码为什么要编译呢。您可以在下面的代码中看到recover不返回单位 object TestRecover { import scala.concurrent.ExecutionContext.Implicit

为什么scala代码要编译, recover的签名是

def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U]
那么下面的代码为什么要编译呢。您可以在下面的代码中看到
recover
不返回单位

 object TestRecover {

    import scala.concurrent.ExecutionContext.Implicits.global
    import scala.concurrent.Future

    def failingFunction(input: Seq[String]): Future[Unit] = {
      Future {
        if (input.isEmpty) throw new Exception("Cannot be empty")
        else ()
      }
    }

    def callFailingFunc(input: Seq[String]): Future[Unit] = {
      failingFunction(input).recover {
        case _ =>
          //Not returning Unit here, but Future[Unit]. Shouldn't type checker fail this ?
          callFailingFunc(input.reverse)
      }
    }
  }
还有为什么
Await.result(TestRecover.callFailingFunc(Seq()),20.seconds)
不会因为无限递归而产生堆栈溢出

那么下面的代码为什么要编译呢。您可以看到,下面代码中的recover不返回单位

编译器正在“帮助”您,并执行从
Future[Unit]
Unit
的隐式转换。像这样有效地编译它

def callFailingFunc(input: Seq[String]): Future[Unit] = {
  failingFunction(input).recover {
    case _ =>
      //Not returning Unit here, but Future[Unit]. Shouldn't type checker fail this ?
      callFailingFunc(input.reverse)
      ()
  }
}
这篇博客很好地解释了:

还有,为什么wait.result(TestRecover.callFailingFunc(Seq()),20.seconds)不会因为无限递归而产生堆栈溢出

不会出现堆栈溢出,因为每次调用
failingFunction
都会创建一个新的
Future
,其中包含一个新堆栈