Respuestas:
No, no puedes abortar un "cada" sin lanzar una excepción. Es probable que desee un bucle clásico si desea que el descanso se cancele bajo una condición particular.
Alternativamente, podría usar un cierre "buscar" en lugar de un cada y devolver verdadero cuando hubiera hecho un descanso.
Este ejemplo abortará antes de procesar toda la lista:
def a = [1, 2, 3, 4, 5, 6, 7]
a.find {
if (it > 5) return true // break
println it // do the stuff that you wanted to before break
return false // keep looping
}
Huellas dactilares
1
2
3
4
5
pero no imprime 6 o 7.
También es realmente fácil escribir sus propios métodos de iterador con un comportamiento de interrupción personalizado que acepte cierres:
List.metaClass.eachUntilGreaterThanFive = { closure ->
for ( value in delegate ) {
if ( value > 5 ) break
closure(value)
}
}
def a = [1, 2, 3, 4, 5, 6, 7]
a.eachUntilGreaterThanFive {
println it
}
También imprime:
1
2
3
4
5
find
mejor que any
- vea la otra respuesta a continuación de @Michal que me funciona
def test = [2] test.findResult{ it * 2 }
devolverá 4 en lugar de 2
Reemplace cada lazo con cualquier cierre.
def list = [1, 2, 3, 4, 5]
list.any { element ->
if (element == 2)
return // continue
println element
if (element == 3)
return true // break
}
Salida
1
3
any()
de esta manera es un poco engañoso, pero ciertamente funciona y le brinda la capacidad de interrumpir o continuar .
No, no puedes romper un cierre en Groovy sin lanzar una excepción. Además, no debe usar excepciones para el flujo de control.
Si te encuentras con ganas de salir de un cierre, probablemente primero deberías pensar por qué quieres hacer esto y no cómo hacerlo. Lo primero a considerar podría ser la sustitución del cierre en cuestión con una de las funciones de orden superior (conceptual) de Groovy. El siguiente ejemplo:
for ( i in 1..10) { if (i < 5) println i; else return}
se convierte
(1..10).each{if (it < 5) println it}
se convierte
(1..10).findAll{it < 5}.each{println it}
lo que también ayuda a la claridad. Establece la intención de su código mucho mejor.
El inconveniente potencial en los ejemplos mostrados es que la iteración solo se detiene temprano en el primer ejemplo. Si tiene consideraciones de rendimiento, es posible que desee detenerlo en ese momento.
Sin embargo, para la mayoría de los casos de uso que involucran iteraciones, generalmente puede recurrir a uno de los métodos de búsqueda, grep, recolección, inyección, etc. de Groovy. Por lo general, toman algo de "configuración" y luego "saben" cómo hacer la iteración por usted, para que pueda evitar el bucle imperativo siempre que sea posible.
Solo usando un cierre especial
// declare and implement:
def eachWithBreak = { list, Closure c ->
boolean bBreak = false
list.each() { it ->
if (bBreak) return
bBreak = c(it)
}
}
def list = [1,2,3,4,5,6]
eachWithBreak list, { it ->
if (it > 3) return true // break 'eachWithBreak'
println it
return false // next it
}
(1..10) .cada {
si (es <5)
imprimirlo
más
falso retorno
each
, simplemente no imprime valores mayores que 4. else
Es superfluo, su código haría lo mismo sin él. Además, puedes probar each
que no se rompe return false
si pones println "not breaking"
justo después else
y justo antes return false
.
Podrías pasar por aquí RETURN
. Por ejemplo
def a = [1, 2, 3, 4, 5, 6, 7]
def ret = 0
a.each {def n ->
if (n > 5) {
ret = n
return ret
}
}
¡Esto funciona para mi!
any
método de la matriz volviendo false
. No puede romper el each
método de la misma manera.