你能从一个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 } } 

这个对我有用!