Groovy Closure中的变量范围(全局变量和函数参数具有相同的名称)

时间:2018-05-22 06:22:29

标签: groovy

我是Groovy的新手,并且对闭包中的变量范围感到困惑。

例如,下面的代码工作正常。它打印两个5。

def x = 10
def y = 25

def myfunc(x) {
  return {
      println(x)
      insideFunc(x)
  }
}

def insideFunc(x) {
    println(x)
}

closureFunc = myfunc(5)

closureFunc.call()

但是下面的代码会显示错误: groovy.lang.MissingPropertyException:没有这样的属性:x表示类。为什么?我认为insideFunc可以访问全局变量'x'?

def x = 10
def y = 25

def myfunc(x) {
  return {
      println(x)
      insideFunc()
  }
}

def insideFunc() {
    println(x)
}

closureFunc = myfunc(5)

closureFunc.call()

1 个答案:

答案 0 :(得分:1)

第二个脚本的问题是由于脚本的执行方式。 xrun方法中是本地范围的。当人们看到脚本在执行时变成什么时,这应该变得明显。从groovyConsole,以下是“Inspect AST”显示的内容(这是不完整的):

public class script1526974299557 extends groovy.lang.Script { 

    ...

    public java.lang.Object run() {
        java.lang.Object x = 10
        java.lang.Object y = 25
        closureFunc = this.myfunc(5)
        closureFunc.call()
    }

    public java.lang.Object myfunc(java.lang.Object x) {
        return { 
            this.println(x)
            this.insideFunc()
        }
    }

    public java.lang.Object insideFunc() {
        this.println(x)
    }
}

显然,x超出了insideFunc()的范围。

然而,关于第一个版本,事情看起来不同。当insideFunc()接受一个参数时,它的参数由闭包进行:

public class script1526974614817 extends groovy.lang.Script { 

    ...

    public java.lang.Object myfunc(java.lang.Object x) {
        return { 
            this.println(x)
            this.insideFunc(x)
        }
    }

    public java.lang.Object insideFunc(java.lang.Object x) {
        this.println(x)
    }
}