从异常中恢复,scala Future

时间:2016-03-03 15:51:31

标签: scala

为什么这个scala代码会编译, 恢复的签名是,

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)由于无限递归而不会产生stackoverflow?

1 个答案:

答案 0 :(得分:3)

  

然后为什么下面的代码编译。您可以看到以下代码中的恢复不会返回单位。

编译器正在帮助'稍等,并进行从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)
      ()
  }
}

此博客解释非常好:http://blog.bruchez.name/2012/10/implicit-conversion-to-unit-type-in.html

  

另外为什么Await.result(TestRecover.callFailingFunc(Seq()),20.seconds)由于无限递归而不会产生堆栈溢出?

您不会收到堆栈溢出,因为每次调用failingFunction都会创建一个新的Future堆栈。