For 循环在 Groovy 和 Java 中的工作方式不同 [英] For loop works different in Groovy and Java

查看:26
本文介绍了For 循环在 Groovy 和 Java 中的工作方式不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请看一下groovy中的以下代码片段:

Please take a look at the following code snippet in groovy:

def static void main(String... args) {
    def arr = [1, 2, 3, 4, 5]
    for (int f in arr) {
        Thread.start { print f + ', '}
    }
}
Out: 2, 3, 5, 5, 5,

我对这个输出感到惊讶.为什么5"被打印了好几次?此外,在 Java 中运行等效代码时,一切看起来都不错:

I was surprised by this output. Why "5" was printed several times? Moreover, everything looks good running equivalent code in Java:

public static void main(String[] args) {
    int[] arr = new int[]{1, 2, 3, 4, 5};
    for (int f : arr) {
        new Thread(() -> { System.out.print(f + ", "); }).start();
    }
}
Out: 1, 5, 4, 3, 2,

谁能解释为什么会这样?看起来 groovy 的问题在于 Closure 实现.然而,这种行为非常奇怪.是某种错误还是我只是没有意识到 groovy 是如何工作的?

Can anyone explain why this is the case? Looks like the issue with groovy is in Closure implementation. However, this behaviour is pretty weird. Is it some kind of bug or I just do not realize how groovy works?

谢谢!

推荐答案

Java 闭包在创建时关闭 f 中的不可变值,而 Groovy 闭包关闭可变变量 f.

A Java closure closes over the immutable value in f when created, while the Groovy closure closes over the mutable variable f.

因此,一旦 Groovy 循环完成,f 包含 5 并且碰巧在此之后运行的线程将打印 5.

So once the Groovy loop finishes, f contains 5 and threads that happen to run after that will print 5.

Java 闭包 可以关闭最终或有效最终"的变量引用,这意味着它除了名称之外都是最终的.请参阅 Java 8:Lambdas,第 1 部分.这就是内部类可以做的事情以及一些有用的便利.

Java closures can close over a variable reference that's final or "effectively final" meaning that it’s final in all but name. See Java 8: Lambdas, Part 1. That's what inner classes can do plus some useful convenience.

Groovy 闭包 是非常不同的对象,它们早于 Java 闭包.请参阅 Groovy Closures,其中示例 { ++item }修改封闭范围内的变量.

Groovy closures are very different objects, and they predate Java closures. See Groovy Closures, where the example { ++item } modifies a variable from the enclosing scope.

Groovy 将闭包定义为 Closure 类的实例.它与 Java 8 中的 lambda 表达式 非常不同.委托是 Groovy 闭包中的一个关键概念,它在 lambda 中没有等价物.更改委托或更改闭包的委托策略的能力使在 Groovy 中设计精美的领域特定语言 (DSL) 成为可能.

Groovy defines closures as instances of the Closure class. It makes it very different from lambda expressions in Java 8. Delegation is a key concept in Groovy closures which has no equivalent in lambdas. The ability to change the delegate or change the delegation strategy of closures make it possible to design beautiful domain specific languages (DSLs) in Groovy.

底线 Groovy 旨在成为与 Java 具有最佳阻抗匹配"的动态语言,但现在 Java 具有 lambda,这两种语言继续存在分歧.警告程序员.

Bottom line Groovy aims to be the dynamic language with the best "impedance match" to Java, but now that Java has lambdas, the two languages continue to diverge. Caveat programmer.

这篇关于For 循环在 Groovy 和 Java 中的工作方式不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆