Почему исключение, генерируемое в Try.recover, не прерывает поток выполнения? - PullRequest
2 голосов
/ 25 сентября 2019

Я написал две функции, чтобы проиллюстрировать мою путаницу:

import scala.util.Try

def TryRecover: Unit = {
  Try {
    throw new Exception()
  }.recover {
    case e: Exception => {
      println("caught error")
      throw e
    }
  }

  println("got to the end of TryRecover")
}

def tryCatch: Unit = {
  try {
    throw new Exception()
  } catch {
    case e: Exception => {
      println("caught error")
      throw e
    }
  }

  println("got to the end of tryCatch")
}

TryRecover
tryCatch

Это вывод:

caught error
got to the end of TryRecover
caught error
java.lang.Exception at .tryCatch(<console>:13) ... 30 elided

Я бы не ожидал, что "дошел до конца TryRecover"когда-либо быть напечатанным.Почему throw e в .recover не нарушает поток выполнения?

1 Ответ

4 голосов
/ 25 сентября 2019

Try.recover выполняет переданный в частичном аргументе функции pf внутри другого try-catch

  def recover[U >: T](pf: PartialFunction[Throwable, U]): Try[U] = {
    val marker = Statics.pfMarker
    try {
      val v = pf.applyOrElse(exception, (x: Throwable) => marker)
      if (marker ne v.asInstanceOf[AnyRef]) Success(v.asInstanceOf[U]) else this
    } catch { case NonFatal(e) => Failure(e) }
  }

, так как e перебрасывается pf

{ case e: Exception => println("caught error"); throw e }

recover оценивается как значение Failure, которое является просто обычным значением первого класса, то есть поток выполнения не прерывается.Фактически, мы могли бы сказать, что основная цель Try состоит в том, чтобы поднять небезопасные исключения в обычные значения, чтобы мы не исключали аварийное завершение программы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...