Вот глупый пример, который, я думаю, приведет вас к ответу:
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