Antworten:
Nein, Sie können kein "jedes" abbrechen, ohne eine Ausnahme auszulösen. Sie möchten wahrscheinlich eine klassische Schleife, wenn die Unterbrechung unter bestimmten Bedingungen abgebrochen werden soll.
Alternativ können Sie anstelle eines Verschlusses einen "Find" -Verschluss verwenden und true zurückgeben, wenn Sie eine Pause eingelegt hätten.
Dieses Beispiel wird abgebrochen, bevor die gesamte Liste verarbeitet wird:
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
}
Druckt
1
2
3
4
5
druckt aber nicht 6 oder 7.
Es ist auch sehr einfach, eigene Iteratormethoden mit benutzerdefiniertem Unterbrechungsverhalten zu schreiben, die Abschlüsse akzeptieren:
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
}
Druckt auch:
1
2
3
4
5
find
besser als any
- siehe die andere Antwort unten von @Michal, dass einer für mich arbeitet
def test = [2] test.findResult{ it * 2 }
wird 4 statt 2 zurückgeben
Ersetzen Sie jede Schlaufe durch einen Verschluss.
def list = [1, 2, 3, 4, 5]
list.any { element ->
if (element == 2)
return // continue
println element
if (element == 3)
return true // break
}
Ausgabe
1
3
any()
auf diese Weise ist etwas irreführend, funktioniert aber auf jeden Fall und gibt Ihnen die Möglichkeit, zu brechen oder fortzufahren .
Nein, Sie können in Groovy nicht ohne Ausnahme von einer Schließung abbrechen. Außerdem sollten Sie keine Ausnahmen für den Kontrollfluss verwenden.
Wenn Sie aus einem Verschluss ausbrechen möchten, sollten Sie sich wahrscheinlich zuerst überlegen, warum Sie dies tun möchten und nicht, wie Sie es tun sollen. Das erste, was zu berücksichtigen ist, könnte die Ersetzung des fraglichen Verschlusses durch eine der (konzeptuellen) Funktionen höherer Ordnung von Groovy sein. Das folgende Beispiel:
for ( i in 1..10) { if (i < 5) println i; else return}
wird
(1..10).each{if (it < 5) println it}
wird
(1..10).findAll{it < 5}.each{println it}
das hilft auch Klarheit. Es gibt die Absicht Ihres Codes viel besser an.
Der mögliche Nachteil in den gezeigten Beispielen besteht darin, dass die Iteration im ersten Beispiel nur früh stoppt. Wenn Sie Leistungsüberlegungen haben, möchten Sie diese möglicherweise sofort stoppen.
Für die meisten Anwendungsfälle, die Iterationen beinhalten, können Sie jedoch normalerweise auf eine der Such-, Grep-, Sammel-, Injektions- usw. Methoden von Groovy zurückgreifen. Normalerweise nehmen sie eine "Konfiguration" vor und "wissen" dann, wie die Iteration für Sie durchgeführt wird, damit Sie die imperative Schleife nach Möglichkeit vermeiden können.
Nur mit speziellem Verschluss
// 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) .jedes {
if (it <5)
drucke es aus
sonst
falsch zurückgeben
each
, es druckt einfach keine Werte größer als 4. Das else
ist überflüssig, Ihr Code würde das gleiche ohne es tun. Sie können auch beweisen, dass each
es nicht bricht, return false
wenn Sie println "not breaking"
kurz nach else
und kurz vor setzen return false
.
Du könntest vorbeischauen RETURN
. Beispielsweise
def a = [1, 2, 3, 4, 5, 6, 7]
def ret = 0
a.each {def n ->
if (n > 5) {
ret = n
return ret
}
}
Für mich geht das!
any
Methode des Arrays durch Rückgabe brechen false
. Sie können die each
Methode nicht auf die gleiche Weise unterbrechen.