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
findmelhor 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 eachque não rompe return falsese você colocar println "not breaking"logo depois elsee 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!
anymétodo da matriz retornando false. Você não pode quebrar o eachmétodo da mesma maneira.