2016-03-03 2 views
3

Почему это SCALA код компилируется, Сигнатура восстанавливаемого,оправиться от Exception, 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 из-за бесконечной рекурсии?

ответ

3

то почему ниже подборка кода. Вы можете видеть, что восстановление в нижнем коде не возвращает Unit.

Компилятор «помогает» вам немного и делает неявное преобразование из 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) не производит StackOverflow из-за бесконечной рекурсии?

Вы не получите переполнение стека, потому что каждый вызов failingFunction создаст новый Future с новым стеком.

Смежные вопросы