处理异常后重新执行TRY块

时间:2011-09-07 09:22:42

标签: scala exception-handling continuations

从这个答案开始:

Scala continuation and exception handling

我想知道在处理异常后是否有办法重新执行ENTIRE try块(或示例代码中的ctry块)。

我的意思是,如果resume()操作可以将执行移动到try块的第一个语句,而不是简单地从引发异常的语句恢复执行。

非常感谢!

1 个答案:

答案 0 :(得分:0)

这是一个愚蠢的例子,我认为会引导你回答:

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