你能从一个Groovy“每个”closures?
是否有可能从Groovy .each{Closure}
break
,还是应该使用经典循环?
不,你不能抛弃一个“每个”而不抛出exception。 如果您想在特定条件下中断,您可能需要经典循环。
或者,您可以使用“查找”闭包而不是每个闭包,并在您完成rest时返回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
用任何闭包replace每个循环。
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
不,你不能在没有抛出exception的情况下从Groovy中closures它。 另外,您不应该使用控制stream的exception。
如果你发现自己想要打破封闭,你应该首先考虑你为什么要这样做,而不是如何去做。 首先要考虑的可能是用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等方法之一。 他们通常会采取一些“configuration”,然后“知道”如何为您进行迭代,以便尽可能避免强制循环。
只是使用特殊的closures
// 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)
打印它
其他
返回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 } }
这个对我有用!