breakBir Groovy'den mümkün mü .each{Closure}yoksa bunun yerine klasik bir döngü mi kullanmalıyım?
breakBir Groovy'den mümkün mü .each{Closure}yoksa bunun yerine klasik bir döngü mi kullanmalıyım?
Yanıtlar:
Hayır, bir istisna atmadan "her birini" iptal edemezsiniz. Ara vermenin belirli bir koşulda iptal edilmesini istiyorsanız muhtemelen klasik bir döngü istersiniz.
Alternatif olarak, her biri yerine bir "find" kapaması kullanabilir ve bir mola verdiğinizde true değerini döndürebilirsiniz.
Bu örnek, listenin tamamını işlemeden önce iptal edilecektir:
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
}
Baskılar
1
2
3
4
5
ancak 6 veya 7 yazdırmaz.
Ayrıca, kapanışları kabul eden özel kesme davranışıyla kendi yineleyici yöntemlerinizi yazmak gerçekten kolaydır:
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
}
Ayrıca yazdırır:
1
2
3
4
5
findiyi any- bir kişinin benim için çalıştığını @Michal aşağıdaki diğer cevap bakın
def test = [2] test.findResult{ it * 2 }2 yerine 4 döndürecek
Her bir döngüyü herhangi bir kapakla değiştirin .
def list = [1, 2, 3, 4, 5]
list.any { element ->
if (element == 2)
return // continue
println element
if (element == 3)
return true // break
}
Çıktı
1
3
any()Bu şekilde kullanmak biraz yanıltıcıdır, ancak kesinlikle işe yarar ve size kırılma veya devam etme yeteneği verir .
Hayır, bir istisna atmadan Groovy'deki bir kapanıştan ayrılamazsınız. Ayrıca, kontrol akışı için istisnalar kullanmamalısınız.
Kendinizi bir kapanıştan kurtulmak istiyorsanız, muhtemelen önce bunu neden yapmak istediğinizi değil, bunu nasıl yapmak istediğinizi düşünmelisiniz. Dikkate alınması gereken ilk şey, söz konusu kapağın Groovy'nin (kavramsal) üst düzey işlevlerinden biriyle değiştirilmesi olabilir. Aşağıdaki örnek:
for ( i in 1..10) { if (i < 5) println i; else return}
olur
(1..10).each{if (it < 5) println it}
olur
(1..10).findAll{it < 5}.each{println it}
bu da netliğe yardımcı olur. Kodunuzun amacını çok daha iyi belirtir.
Gösterilen örneklerin potansiyel dezavantajı, yinelemenin sadece ilk örnekte erken durmasıdır. Performansla ilgili düşünceleriniz varsa, o anda ve orada durdurmak isteyebilirsiniz.
Bununla birlikte, yinelemeleri içeren çoğu kullanım durumunda genellikle Groovy'nin bulma, grep, toplama, enjekte etme, vb. Yöntemlerinden birine başvurabilirsiniz. Genellikle bir "yapılandırma" alırlar ve daha sonra sizin için yinelemenin nasıl yapılacağını "bilirler", böylece mümkünse zorunlu döngüden kaçınabilirsiniz.
Sadece özel Kapanış kullanarak
// 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 {
eğer (o <5)
yazdır
Başka
yanlış döndür
each, sadece 4'ten büyük değerleri yazdırmaz. Bu elsegereksizdir, kodunuz onsuz da aynısını yapacaktır. Ayrıca, hemen sonra ve hemen önce koyarsanız eachkırılmadığını kanıtlayabilirsiniz . return falseprintln "not breaking"elsereturn false
Sen kırılabilirsin RETURN. Örneğin
def a = [1, 2, 3, 4, 5, 6, 7]
def ret = 0
a.each {def n ->
if (n > 5) {
ret = n
return ret
}
}
Benim için çalışıyor!
anyDöndürerek dizinin yöntemini kırabilirsiniz false. Sen bozamam eachaynı şekilde yöntemini.