¿Es posible break
desde un Groovy .each{Closure}
, o debería usar un bucle clásico en su lugar?
143
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 queany
- vea la otra respuesta a continuación de @Michal que me funcionadef test = [2] test.findResult{ it * 2 }
devolverá 4 en lugar de 2Reemplace cada lazo con cualquier cierre.
Salida
fuente
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:
se convierte
se convierte
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.
fuente
Solo usando un cierre especial
fuente
(1..10) .cada {
si (es <5)
imprimirlo
más
falso retorno
fuente
each
, simplemente no imprime valores mayores que 4.else
Es superfluo, su código haría lo mismo sin él. Además, puedes probareach
que no se rompereturn false
si ponesprintln "not breaking"
justo despuéselse
y justo antesreturn false
.Podrías pasar por aquí
RETURN
. Por ejemplo¡Esto funciona para mi!
fuente
any
método de la matriz volviendofalse
. No puede romper eleach
método de la misma manera.