Vous pouvez uniquement prendre en charge continuer proprement, ne pas casser. Surtout avec des trucs comme eachLine et chacun. L'incapacité de supporter la rupture a à voir avec la façon dont ces méthodes sont évaluées, il n'y a aucune considération pour ne pas finir la boucle qui peut être communiquée à la méthode. Voici comment prendre en charge continuer -
Meilleure approche (en supposant que vous n'avez pas besoin de la valeur résultante).
revs.eachLine { line ->
if (line ==~ /-{28}/) {
return // returns from the closure
}
}
Si votre échantillon est vraiment aussi simple, c'est bon pour la lisibilité. Une autre option simule ce que ferait normalement une poursuite à un niveau de bytecode.
revs.eachLine { line ->
while (true) {
if (line ==~ /-{28}/) {
break
}
// rest of normal code
break
}
}
Un moyen de soutenir la rupture est par des exceptions:
try {
revs.eachLine { line ->
if (line ==~ /-{28}/) {
throw new Exception("Break")
}
}
} catch (Exception e) { } // just drop the exception
Vous pouvez utiliser un type d'exception personnalisée pour ne pas masquer d'autres exceptions réelles, surtout si vous avez d'autres traitements en cours dans ce classe qui pourrait déclencher des exceptions réelles, comme NumberFormatExceptions ou IOExceptions.
Utilisation d'exceptions pour contrôler le flux de programme est une mauvaise idée. La création d'exceptions nécessite de prendre un instantané de la pile des appels, ce qui est coûteux. –
Pas si vous remplacez la méthode qui génère la pile d'appels dans l'exception que vous lancez pour ne rien faire. C'est l'avantage d'une exception personnalisée. – shemnon
C'est aussi une étape supplémentaire dans un effort pour contourner un problème que vous n'auriez pas si vous utilisiez une fermeture comme une fermeture au lieu de la considérer comme une construction en boucle. L'exemple ci-dessus bénéficierait plus de la fixation de l'intention globale peu claire de la logique à soit filtrer les lignes ou trouver une ligne. – Cliff