Answers:
不,您不能在不引发异常的情况下中止“每个”。如果希望中断在特定条件下中止,则可能需要经典循环。
另外,您可以使用“查找”闭包代替每个闭包,并在需要休息时返回true。
此示例在处理整个列表之前将中止:
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的find,grep,collect,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)。每个{
如果(<5)
打印它
其他
返回假
each
,它只是不会打印大于4的值。else
是多余的,如果没有它,您的代码将执行相同的操作。另外,如果您放置在之前和之后,则可以证明each
不中断。return false
println "not breaking"
else
return false