เป็นไปได้ที่จะ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
3any()วิธีนี้เป็นสิ่งที่ทำให้เข้าใจผิดเล็กน้อย แต่ก็สามารถใช้งานได้และทำให้คุณสามารถทำลายหรือทำต่อไปได้
                    ไม่คุณไม่สามารถหยุดพักจากการหยุดเล่นใน 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วิธีด้วยวิธีเดียวกันได้