Câu trả lời:
Không, bạn không thể hủy bỏ "mỗi" mà không ném ngoại lệ. Bạn có thể muốn một vòng lặp cổ điển nếu bạn muốn nghỉ để hủy bỏ trong một điều kiện cụ thể.
Ngoài ra, bạn có thể sử dụng bao đóng "tìm" thay vì mỗi lần đóng và trả về đúng khi bạn đã nghỉ.
Ví dụ này sẽ hủy bỏ trước khi xử lý toàn bộ danh sách:
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
}
Bản in
1
2
3
4
5
nhưng không in 6 hoặc 7.
Thật dễ dàng để viết các phương thức lặp của riêng bạn với hành vi ngắt tùy chỉnh chấp nhận các bao đóng:
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
}
Cũng in:
1
2
3
4
5
find
tốt hơn so với any
- xem câu trả lời khác dưới đây từ @Michal rằng một công trình đối với tôi
def test = [2] test.findResult{ it * 2 }
sẽ trả về 4 thay vì 2
Thay thế mỗi vòng lặp với bất kỳ đóng cửa.
def list = [1, 2, 3, 4, 5]
list.any { element ->
if (element == 2)
return // continue
println element
if (element == 3)
return true // break
}
Đầu ra
1
3
any()
theo cách này là một chút sai lệch, nhưng nó chắc chắn có tác dụng và cung cấp cho bạn khả năng phá vỡ hoặc tiếp tục .
Không, bạn không thể thoát khỏi việc đóng cửa trong Groovy mà không ném ngoại lệ. Ngoài ra, bạn không nên sử dụng ngoại lệ cho luồng điều khiển.
Nếu bạn thấy mình muốn thoát ra khỏi sự đóng cửa, trước tiên bạn có thể nên nghĩ về lý do tại sao bạn muốn làm điều này chứ không phải làm thế nào để làm điều đó. Điều đầu tiên cần xem xét có thể là sự thay thế của bao đóng trong câu hỏi bằng một trong các hàm bậc cao hơn (khái niệm) của Groovy. Ví dụ sau:
for ( i in 1..10) { if (i < 5) println i; else return}
trở thành
(1..10).each{if (it < 5) println it}
trở thành
(1..10).findAll{it < 5}.each{println it}
Điều này cũng giúp rõ ràng. Nó nêu ý định của mã của bạn tốt hơn nhiều.
Hạn chế tiềm năng trong các ví dụ được hiển thị là việc lặp lại chỉ dừng lại sớm trong ví dụ đầu tiên. Nếu bạn có những cân nhắc về hiệu suất, bạn có thể muốn dừng nó ngay lúc đó và ở đó.
Tuy nhiên, đối với hầu hết các trường hợp sử dụng liên quan đến các lần lặp, bạn thường có thể sử dụng một trong các phương pháp tìm, grep, thu thập, tiêm, v.v. của Groovy. Họ thường lấy một số "cấu hình" và sau đó "biết" cách thực hiện phép lặp cho bạn, để bạn thực sự có thể tránh vòng lặp bắt buộc bất cứ khi nào có thể.
Chỉ cần sử dụng đóng cửa đặc biệt
// 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 {
nếu (nó <5)
in nó
khác
trả lại sai
each
, nó chỉ đơn giản là không in các giá trị lớn hơn 4. Điều else
này là thừa, mã của bạn sẽ làm như vậy mà không có nó. Ngoài ra, bạn có thể chứng minh each
không phá vỡ return false
nếu bạn đặt println "not breaking"
ngay sau else
và ngay trước đó return false
.
Bạn có thể vượt qua RETURN
. Ví dụ
def a = [1, 2, 3, 4, 5, 6, 7]
def ret = 0
a.each {def n ->
if (n > 5) {
ret = n
return ret
}
}
Nó làm việc cho tôi!
any
phương thức của mảng bằng cách trả về false
. Bạn không thể phá vỡ each
phương thức theo cùng một cách.