Est-il possible de break
partir d'un Groovy .each{Closure}
ou devrais-je utiliser une boucle classique à la place?
143
Non, vous ne pouvez pas abandonner un «chacun» sans lancer une exception. Vous souhaiterez probablement une boucle classique si vous souhaitez que l'interruption s'interrompe dans une condition particulière.
Alternativement, vous pouvez utiliser une fermeture «find» au lieu d'un each et retourner true lorsque vous auriez fait une pause.
Cet exemple s'arrêtera avant de traiter toute la liste:
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
}
Tirages
1
2
3
4
5
mais n'imprime pas 6 ou 7.
Il est également très facile d'écrire vos propres méthodes d'itération avec un comportement de rupture personnalisé qui accepte les fermetures:
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
}
Imprime également:
1
2
3
4
5
find
mieux queany
- voir l'autre réponse ci-dessous de @Michal que l'on travaille pour moidef test = [2] test.findResult{ it * 2 }
retournera 4 au lieu de 2Remplacez chaque boucle par n'importe quelle fermeture.
Production
la source
any()
de cette manière est un peu trompeur, mais cela fonctionne certainement et vous donne la possibilité de rompre ou de continuer .Non, vous ne pouvez pas rompre avec une fermeture dans Groovy sans lancer une exception. De plus, vous ne devez pas utiliser d'exceptions pour le flux de contrôle.
Si vous avez envie de sortir d'une clôture, vous devriez probablement d'abord vous demander pourquoi vous voulez faire cela et non comment le faire. La première chose à considérer pourrait être la substitution de la fermeture en question par l'une des fonctions d'ordre supérieur (conceptuel) de Groovy. L'exemple suivant:
devient
devient
ce qui contribue également à la clarté. Il énonce bien mieux l'intention de votre code.
L'inconvénient potentiel des exemples illustrés est que l'itération ne s'arrête que tôt dans le premier exemple. Si vous avez des considérations de performances, vous voudrez peut-être l'arrêter immédiatement.
Cependant, pour la plupart des cas d'utilisation qui impliquent des itérations, vous pouvez généralement recourir à l'une des méthodes find, grep, collect, inject, etc. de Groovy. Ils prennent généralement une certaine "configuration" et ensuite "savent" comment faire l'itération pour vous, de sorte que vous puissiez réellement éviter les boucles impératives dans la mesure du possible.
la source
Juste en utilisant une fermeture spéciale
la source
(1..10) .chaque {
si (il <5)
imprimer
autre
retourner faux
la source
each
, il n'imprime tout simplement pas les valeurs supérieures à 4. C'estelse
superflu, votre code ferait de même sans lui. En outre, vous pouvez prouvereach
que vous ne rompez pas avecreturn false
si vous mettezprintln "not breaking"
juste aprèselse
et juste avantreturn false
.Vous pourriez passer
RETURN
. Par exempleÇa marche pour moi!
la source
any
méthode du tableau en retournantfalse
. Vous ne pouvez pas interrompre laeach
méthode de la même manière.