เป็นไปได้ที่จะbreak
มาจาก Groovy .each{Closure}
หรือฉันควรจะใช้วนรอบแบบคลาสสิกแทน?
เป็นไปได้ที่จะbreak
มาจาก Groovy .each{Closure}
หรือฉันควรจะใช้วนรอบแบบคลาสสิกแทน?
คำตอบ:
ไม่คุณไม่สามารถยกเลิก "แต่ละคน" ได้โดยไม่ต้องทำการยกเว้น คุณอาจต้องการวนรอบแบบคลาสสิกหากคุณต้องการหยุดพักเพื่อยกเลิกภายใต้เงื่อนไขเฉพาะ
หรือคุณสามารถใช้การปิด "ค้นหา" แทนการปิดแต่ละรายการและคืนค่าจริงเมื่อคุณหยุดพัก
ตัวอย่างนี้จะยกเลิกก่อนที่จะประมวลผลรายการทั้งหมด:
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
}
พิมพ์
1
2
3
4
5
แต่ไม่พิมพ์ 6 หรือ 7
นอกจากนี้ยังง่ายมากในการเขียนวิธีการวนซ้ำของคุณเองด้วยพฤติกรรมการพักแบบกำหนดเองที่ยอมรับการปิด:
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
}
พิมพ์ด้วย:
1
2
3
4
5
find
ดีกว่าany
- ดูคำตอบอื่น ๆ ด้านล่างจาก @Michal ที่หนึ่งงานสำหรับฉัน
def test = [2] test.findResult{ it * 2 }
จะกลับ 4 แทน 2
แทนที่แต่ละวงด้วยการปิดใด ๆ
def list = [1, 2, 3, 4, 5]
list.any { element ->
if (element == 2)
return // continue
println element
if (element == 3)
return true // break
}
เอาท์พุต
1
3
any()
วิธีนี้เป็นสิ่งที่ทำให้เข้าใจผิดเล็กน้อย แต่ก็สามารถใช้งานได้และทำให้คุณสามารถทำลายหรือทำต่อไปได้
ไม่คุณไม่สามารถหยุดพักจากการหยุดเล่นใน Groovy ได้โดยไม่ต้องทำการยกเว้น นอกจากนี้คุณไม่ควรใช้ข้อยกเว้นสำหรับโฟลว์การควบคุม
หากคุณพบว่าตัวเองต้องการแยกจากการปิดคุณควรคิดก่อนว่าทำไมคุณถึงต้องการทำสิ่งนี้และไม่ใช่วิธีการทำ สิ่งแรกที่ควรพิจารณาคือการทดแทนการปิดในคำถามด้วยหนึ่งในฟังก์ชันลำดับที่สูงขึ้นของ Groovy (แนวคิด) ตัวอย่างต่อไปนี้:
for ( i in 1..10) { if (i < 5) println i; else return}
กลายเป็น
(1..10).each{if (it < 5) println it}
กลายเป็น
(1..10).findAll{it < 5}.each{println it}
ซึ่งยังช่วยให้ชัดเจน มันระบุเจตนาของรหัสของคุณได้ดีขึ้นมาก
ข้อเสียเปรียบที่อาจเกิดขึ้นในตัวอย่างที่แสดงคือการวนซ้ำจะหยุดก่อนในตัวอย่างแรกเท่านั้น หากคุณมีข้อควรพิจารณาเกี่ยวกับประสิทธิภาพคุณอาจต้องการหยุดมันทันที
อย่างไรก็ตามสำหรับกรณีการใช้งานส่วนใหญ่ที่เกี่ยวข้องกับการทำซ้ำคุณมักจะใช้วิธีการค้นหาอย่างใดอย่างหนึ่งของ Groovy, grep, รวบรวม, inject, ฯลฯ พวกเขามักจะใช้ "การกำหนดค่า" และ "รู้" วิธีการทำซ้ำสำหรับคุณเพื่อให้คุณสามารถหลีกเลี่ยงการวนซ้ำที่จำเป็นได้ทุกที่ที่เป็นไปได้
เพียงแค่ใช้การปิดแบบพิเศษ
// 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 {
ถ้า (มัน <5)
ปริ้นมัน
อื่น
กลับเท็จ
each
กัน แต่ก็ไม่ได้พิมพ์ค่าที่มากกว่า 4 ซึ่งelse
ไม่จำเป็นเลยรหัสของคุณจะทำแบบเดียวกันหากไม่มีมัน นอกจากนี้คุณยังสามารถพิสูจน์ได้each
ไม่ทำลายด้วยreturn false
ถ้าคุณใส่println "not breaking"
หลังและก่อนelse
return false
RETURN
คุณสามารถทำลายโดย ตัวอย่างเช่น
def a = [1, 2, 3, 4, 5, 6, 7]
def ret = 0
a.each {def n ->
if (n > 5) {
ret = n
return ret
}
}
มันใช้งานได้สำหรับฉัน!
any
false
คุณไม่สามารถแยกeach
วิธีด้วยวิธีเดียวกันได้