Jawaban:
Tidak, Anda tidak dapat membatalkan "masing-masing" tanpa melemparkan pengecualian. Anda mungkin menginginkan loop klasik jika Anda ingin jeda untuk dibatalkan dalam kondisi tertentu.
Atau, Anda bisa menggunakan penutupan "find" alih-alih setiap dan mengembalikan true ketika Anda akan melakukan break.
Contoh ini akan dibatalkan sebelum memproses seluruh daftar:
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
}
Cetakan
1
2
3
4
5
tetapi tidak mencetak 6 atau 7.
Juga sangat mudah untuk menulis metode iterator Anda sendiri dengan perilaku istirahat kustom yang menerima penutupan:
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
}
Juga mencetak:
1
2
3
4
5
find
lebih baik daripada any
- lihat jawaban lain di bawah ini dari @Michal yang satu bekerja untuk saya
def test = [2] test.findResult{ it * 2 }
akan mengembalikan 4 bukannya 2
Ganti setiap loop dengan penutupan apa pun .
def list = [1, 2, 3, 4, 5]
list.any { element ->
if (element == 2)
return // continue
println element
if (element == 3)
return true // break
}
Keluaran
1
3
any()
cara ini agak menyesatkan, tetapi tentu saja itu berhasil dan memberi Anda kemampuan untuk istirahat atau melanjutkan .
Tidak, Anda tidak dapat melepaskan diri dari penutupan di Groovy tanpa melempar pengecualian. Selain itu, Anda tidak boleh menggunakan pengecualian untuk aliran kontrol.
Jika Anda mendapati diri Anda ingin keluar dari penutupan, Anda mungkin harus terlebih dahulu memikirkan mengapa Anda ingin melakukan ini dan bukan bagaimana melakukannya. Hal pertama yang harus dipertimbangkan adalah penggantian penutupan yang dipertanyakan dengan salah satu fungsi tingkat tinggi Groovy (konseptual). Contoh berikut:
for ( i in 1..10) { if (i < 5) println i; else return}
menjadi
(1..10).each{if (it < 5) println it}
menjadi
(1..10).findAll{it < 5}.each{println it}
yang juga membantu kejelasan. Ini menyatakan maksud dari kode Anda jauh lebih baik.
Kelemahan potensial dalam contoh yang ditunjukkan adalah bahwa iterasi hanya berhenti lebih awal pada contoh pertama. Jika Anda memiliki pertimbangan kinerja, Anda mungkin ingin menghentikannya saat itu juga.
Namun, untuk sebagian besar kasus penggunaan yang melibatkan iterasi, Anda biasanya dapat menggunakan salah satu dari metode penemuan, penjelajahan, pengumpulan, injeksi, dll. Mereka biasanya mengambil beberapa "konfigurasi" dan kemudian "tahu" bagaimana melakukan iterasi untuk Anda, sehingga Anda benar-benar dapat menghindari perulangan imperatif sedapat mungkin.
Hanya menggunakan Penutupan khusus
// 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). Masing-masing {
jika (<5)
cetak itu
lain
kembali salah
each
, itu hanya tidak mencetak nilai lebih besar dari 4. Hal else
ini berlebihan, kode Anda akan melakukan hal yang sama tanpanya. Juga, Anda dapat membuktikan each
tidak putus dengan return false
jika Anda memasukkan println "not breaking"
setelah else
dan sebelum return false
.
Anda bisa istirahat RETURN
. Sebagai contoh
def a = [1, 2, 3, 4, 5, 6, 7]
def ret = 0
a.each {def n ->
if (n > 5) {
ret = n
return ret
}
}
Ini bekerja untuk saya!
any
metode array dengan kembali false
. Anda tidak dapat merusak each
metode dengan cara yang sama.