Повторно выполнить блок TRY после обработки исключения - PullRequest
0 голосов
/ 07 сентября 2011

Начиная с этого ответа:

Продолжение Scala и обработка исключений

Я хотел бы знать, есть ли способ повторно выполнить ВЕСЬ блок try (или блок ctry в примере кода) после обработки исключения.

Я имею в виду, что операция resume () могла бы переместить выполнение в первый оператор блока try вместо простого возобновления выполнения из оператора, вызвавшего исключение.

Большое спасибо!

1 Ответ

0 голосов
/ 23 июня 2013

Вот глупый пример, который, я думаю, приведет вас к ответу:

object Retry

object SO_7331489 extends App {

  import scala.util.continuations._

  var dividend: String = "ten"
  var divisor: Int = 0

  val quotient = reset {

    shift { k: (Unit => Any) =>
      def retry: Any =
        k() match {
          case Retry => retry
          case x     => x
        }
      retry
    }

    try {
      dividend.toInt / divisor
    } catch {
      case e: java.lang.NumberFormatException =>
        println("caught " + e.getClass.getName + "(" + e.getMessage + ")")
        dividend = "10"
        println("retrying with dividend = \"10\"")
        Retry
      case e: java.lang.ArithmeticException =>
        println("caught " + e.getClass.getName + "(" + e.getMessage + ")")
        divisor = 2
        println("retrying with divisor = 2")
        Retry
      case t: Throwable =>
        println("caught " + t.getClass.getName + "(" + t.getMessage + ")")
        // Nothing left to retry, so don't return Retry
    }

  }

  println("quotient: " + quotient)

}

Идея состоит в том, чтобы запустить блок shift перед вашим блоком try/catch. В пределах блока catch, если вы хотите повторить все это, просто верните объект Retry.

Было бы неплохо вытащить весь блок shift в простую функцию (например, retry), но я оставил его встроенным для ясности.

Этот код выдает следующий вывод:

[info] Running SO_7331489 
caught java.lang.NumberFormatException(For input string: "ten")
retrying with dividend = "10"
caught java.lang.ArithmeticException(/ by zero)
retrying with divisor = 2
quotient: 5
...