Respostas:
Não, você não pode abortar um "cada" sem lançar uma exceção. Você provavelmente deseja um loop clássico se quiser que a interrupção seja interrompida sob uma condição específica.
Como alternativa, você poderia usar um fechamento "find" em vez de um each e retornar true quando você tivesse feito uma pausa.
Este exemplo será interrompido antes de processar a lista inteira:
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
}
Impressões
1
2
3
4
5
mas não imprime 6 ou 7.
Também é muito fácil escrever seus próprios métodos de iterador com comportamento de interrupção personalizado que aceita fechamentos:
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
}
Também imprime:
1
2
3
4
5
find
melhor do que any
- veja a outra resposta abaixo de @Michal que um funciona para mim
def test = [2] test.findResult{ it * 2 }
retornará 4 em vez de 2
Substitua cada loop por qualquer fechamento.
def list = [1, 2, 3, 4, 5]
list.any { element ->
if (element == 2)
return // continue
println element
if (element == 3)
return true // break
}
Resultado
1
3
any()
dessa maneira é um pouco enganador, mas certamente funciona e permite que você quebre ou continue .
Não, você não pode interromper um fechamento no Groovy sem lançar uma exceção. Além disso, você não deve usar exceções para o fluxo de controle.
Se você deseja interromper um fechamento, provavelmente deve primeiro pensar por que deseja fazer isso e não como fazê-lo. A primeira coisa a considerar poderia ser a substituição do fechamento em questão por uma das funções de ordem superior (conceitual) de Groovy. O exemplo a seguir:
for ( i in 1..10) { if (i < 5) println i; else return}
torna-se
(1..10).each{if (it < 5) println it}
torna-se
(1..10).findAll{it < 5}.each{println it}
o que também ajuda na clareza. Ele afirma a intenção do seu código muito melhor.
A desvantagem potencial nos exemplos mostrados é que a iteração para apenas no início do primeiro exemplo. Se você tiver considerações de desempenho, poderá interrompê-lo imediatamente.
No entanto, para a maioria dos casos de uso que envolvem iterações, você geralmente pode recorrer a um dos métodos de descoberta, grep, coleta, injeção, etc. do Groovy. Eles geralmente usam alguma "configuração" e, em seguida, "sabem" como fazer a iteração para você, para que você possa evitar o loop imperativo sempre que possível.
Apenas usando Fechamento 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) .each {
se (<5)
imprima
outro
retorna falso
each
, simplesmente não imprime valores maiores que 4. Isso else
é supérfluo, seu código faria o mesmo sem ele. Além disso, você pode provar each
que não rompe return false
se você colocar println "not breaking"
logo depois else
e pouco antes return false
.
Você poderia passar por aqui RETURN
. Por exemplo
def a = [1, 2, 3, 4, 5, 6, 7]
def ret = 0
a.each {def n ->
if (n > 5) {
ret = n
return ret
}
}
Funciona para mim!
any
método da matriz retornando false
. Você não pode quebrar o each
método da mesma maneira.