Al saltar fuera del bucle en Java, podemos simplemente romper directamente, pero no hay ruptura en scala, entonces, ¿cómo salir del bucle?
Mire directamente la demostración a continuación:
package test
import scala.util.control.Breaks
object ListDemo {
def main(args: Array[String]): Unit = {
var loop = Breaks
var i = 0
loop.breakable {
while (i < 10) {
println(i)
i += 1
if (i == 5) {
loop.break()
}
}
}
}
}
Este lugar debe incluirse con loop.breakable; de lo contrario, se informará un error
Excepción en el hilo "principal" scala.util.control.BreakControl
Echemos un vistazo al código fuente de Breaks:
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala
package util.control
/** A class that can be instantiated for the break control abstraction.
* Example usage:
* {
{
{
* val mybreaks = new Breaks
* import mybreaks.{break, breakable}
*
* breakable {
* for (...) {
* if (...) break()
* }
* }
* }}}
* Calls to break from one instantiation of `Breaks` will never
* target breakable objects of some other instantiation.
*/
class Breaks {
private val breakException = new BreakControl
/**
* A block from which one can exit with a `break`. The `break` may be
* executed further down in the call stack provided that it is called on the
* exact same instance of `Breaks`.
*/
def breakable(op: => Unit) {
try {
op
} catch {
case ex: BreakControl =>
if (ex ne breakException) throw ex
}
}
sealed trait TryBlock[T] {
def catchBreak(onBreak: =>T): T
}
/**
* This variant enables the execution of a code block in case of a `break()`:
* {
{
{
* tryBreakable {
* for (...) {
* if (...) break()
* }
* } catchBreak {
* doCleanup()
* }
* }}}
*/
def tryBreakable[T](op: =>T) = new TryBlock[T] {
def catchBreak(onBreak: =>T) = try {
op
} catch {
case ex: BreakControl =>
if (ex ne breakException) throw ex
onBreak
}
}
/**
* Break from dynamically closest enclosing breakable block using this exact
* `Breaks` instance.
*
* @note This might be different than the statically closest enclosing block!
*/
def break(): Nothing = { throw breakException }
}
/** An object that can be used for the break control abstraction.
* Example usage:
* {
{
{
* import Breaks.{break, breakable}
*
* breakable {
* for (...) {
* if (...) break
* }
* }
* }}}
*/
object Breaks extends Breaks
private class BreakControl extends ControlThrowable
Como se puede ver en el código fuente anterior, el principio de combinar métodos rompibles y de ruptura para controlar el bucle es usar el método de ruptura para lanzar una excepción, y luego el método rompible captura la excepción, terminando así la ejecución del código en todo el bloque del método rompible, pero no afecta la ejecución del código in vitro del método rompible, para lograr el control.
Si hay algún problema, corríjame. Si tiene alguna pregunta, puede agregar el grupo QQ: 340297350 Gracias