【问题标题】:When to use `each` and when to use the `for` loop in Groovy在 Groovy 中何时使用“each”以及何时使用“for”循环
【发布时间】:2023-03-19 06:07:01
【问题描述】:

我们什么时候使用 each 闭包,什么时候在 Groovy 中使用 for 循环。两者都有效地做同样的事情。

groovy:000> a = [1, 2, 3, 4]
===> [1, 2, 3, 4]
groovy:000> a.each {
groovy:001> println it
groovy:002> }
1
2
3
4
===> [1, 2, 3, 4]
groovy:000> for (it in a) {
groovy:001> println it
groovy:002> }
1
2
3
4
===> null

each 闭包返回列表。所以我可能可以使用它来代替for 循环,但反之亦然,对吗?

【问题讨论】:

标签: loops for-loop groovy closures


【解决方案1】:

for 循环可能更快,内存效率更高,因为 each 构造是语法糖。但我无法想象它会真正发挥作用的情况。

在我看来,唯一显着的区别是你不能在不抛出异常的情况下终止每个闭包。您可以使用 break 来终止 for 循环。

我确实认为 each 结构读起来更惯用。

【讨论】:

  • 好点。但是您认为仅此而已还是还有更多。
  • @aa8y - 您可以使用这两个版本反编译一个简单的类,并查看生成的字节码以了解每个版本的作用。不过,一般来说,Groovy 迭代构造比简单循环的开销要多一些,所以如果你真的需要额外的性能......
【解决方案2】:

for 循环在这个question 和这个answer 中更快,但请记住,过早的优化是编程中万恶之源,所以我找不到任何它确实有所作为的场景。

each 还返回它正在操作的整个未修改的集合,here 是 OP 发现它有用的特定场景。 for 构造不返回任何内容。

【讨论】:

    【解决方案3】:

    一般 Groovier 更喜欢each,因为将来更改代码会更容易。 each 方法与 Groovy 中普遍存在的一系列函数方法有关;相比之下,for 循环陷入了 Java 的命令式风格。

    作为一个起始示例,假设我们希望 foo 为每个项目调用 bar

    def bar = { println it }
    
    def foo = { def a ->
        a.each { bar it }
    }
    
    foo( [1,2,3,4] )
    

    现在,如果我们只想为偶数调用 bar 怎么办:

    def bar = { println it }
    
    def foo = { def a ->
        a.findAll{ (it % 2) == 0 }.each{ bar it }
    }
    
    foo( [1,2,3,4] )
    

    如果我们发现bar需要item的列表索引怎么办?

    def bar = { def item, def index -> println "${index} ${item}" }
    
    def foo = { def a ->
        a.eachWithIndex{ def x, def i -> bar x, i }
    }
    
    foo( [1,2,3,4] )
    

    尝试使用for 循环编写这些示例。当然,它可以做到,但这些变化似乎并不优雅。 (注意,如 cmets 中所述,您将要学习 collect 和其他方法。Foreach 有点错误的二分法。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-12
      • 1970-01-01
      • 2016-07-26
      • 2017-02-02
      • 1970-01-01
      相关资源
      最近更新 更多