É possível a break
partir de um Groovy .each{Closure}
, ou devo usar um loop clássico?
143
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 queany
- veja a outra resposta abaixo de @Michal que um funciona para mimdef test = [2] test.findResult{ it * 2 }
retornará 4 em vez de 2Substitua cada loop por qualquer fechamento.
Resultado
fonte
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:
torna-se
torna-se
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.
fonte
Apenas usando Fechamento especial
fonte
(1..10) .each {
se (<5)
imprima
outro
retorna falso
fonte
each
, simplesmente não imprime valores maiores que 4. Issoelse
é supérfluo, seu código faria o mesmo sem ele. Além disso, você pode provareach
que não rompereturn false
se você colocarprintln "not breaking"
logo depoiselse
e pouco antesreturn false
.Você poderia passar por aqui
RETURN
. Por exemploFunciona para mim!
fonte
any
método da matriz retornandofalse
. Você não pode quebrar oeach
método da mesma maneira.