For循环在Groovy和Java中有所不同 [英] For loop works different in Groovy and Java

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

问题描述

请查看 groovy 中的以下代码段:

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

我对这个输出感到惊讶。为什么5被多次打印?
此外,在 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();


出:1,5,4,3,2,

任何人都可以解释为什么会出现这种情况吗?看起来groovy的问题在Closure实现中。但是,这种行为很奇怪。它是一种错误,或者我只是不知道groovy是如何工作的?

谢谢!

解决方案

当创建时,Java闭包关闭 c 中的不可变值,而Groovy闭包关闭于可变变量 f



所以一旦Groovy循环完成, f 包含 5 ,并且在那之后运行的线程将打印 5 。 p>

Java关闭可以关闭一个变量引用,这个引用是最终的或有效的最终,这意味着它的名字是最终的。请参阅 Java 8:Lambdas,第1部分。这就是内部类可以做的事情,以及一些有用的便利。

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


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




Groovy的目标是成为与Java最好的阻抗匹配的动态语言,但现在Java已经有了lambda表达式,这两种语言仍然存在分歧。警告程序员。

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,

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,

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?

Thanks!

解决方案

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

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

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 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 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.

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天全站免登陆