Вот глупый пример, который я думаю, что будет направлять вас к ответу:
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
Я думаю, что это называется «петля». –
Хорошо, следующий вопрос. Предположим, что блок try вызывает исключение. В блоке catch я меняю код внутри блока try (используя байт-код или перекомпилированный исходный код). Есть способ повторного выполнения блока NEW try? –
@Niko - Я не понимаю, что вы подразумеваете, изменяя код в блоке catch. Вы динамически перезагружаете определение класса в приложении, а программа находится внутри этого класса? Не очевидно, как вы это сделаете (или это то, что вы имеете в виду), поэтому более подробная информация будет очень полезна. –