在静态范围内访问全局变量

时间:2016-02-15 19:58:06

标签: groovy

有没有办法从同一脚本中声明的类的静态方法访问脚本中声明的全局变量?

例如

def s = "12345"

class MyClass {
    static def method() {
        println s
    }
}

因为这种方式失败并出现错误

You attempted to reference a variable in the binding or an instance variable from a static context

这是预期的。

3 个答案:

答案 0 :(得分:8)

在这个问题上有一个相关的讨论:

Groovy scope - how to access script variable in a method

相关的是,这两个问题都是指在类中使用全局变量,但这个问题在某种程度上有所不同,因为您正在寻求使用静态方法来改变您传递脚本实例或绑定的方式(2个选项)。

传递脚本的实例

import groovy.transform.Field

@Field def s = "12345"

class MyClass {
    static def method(si) {      
      return si.s
    }
}

assert MyClass.method(this) == "12345"

传递脚本的绑定

s = "12345" // NOTE: no 'def'

class MyClass {
    static def method(b) {      
      return b.s
    }
}

assert MyClass.method(binding) == "12345"

答案 1 :(得分:4)

嗯,问题是在Groovy中没有全局变量这样的东西。宽松地认为全局变量实际上是某个类中的静态属性。

例如,如果您删除 println 行以便代码编译,那么您可以从编译器中获得类似的内容:

public class script1455567284805 extends groovy.lang.Script { 

    ...

    public java.lang.Object run() {
        return java.lang.Object s = '12345'
    }

    ...

}

public class MyClass implements groovy.lang.GroovyObject extends java.lang.Object { 

    ...

    public static java.lang.Object method() {
        // This is where the println would have been.
        return null
    }

    ...
}

如您所见,创建了一个附加类,并在该类的方法s中声明了run()变量。这使得变量无法访问其他类。

注意:删除def无法解决此问题。

解决方案

您最好的选择是放置全局变量"进入一个类,可能是静态属性,如下所示:

class Global {
    static Object S = "12345"
}

class MyClass {
    static def method() {
        println Global.S
    }
}

答案 2 :(得分:1)

您包含了带s变量的变量类型(使用def类型)。在Groovy脚本中,这被视为局部变量 - 并且是生成的run()方法的本地变量 - 有点像main()类。因此,该变量在其他方法或类中不可用。

如果您移除def,则可以使用s变量。

以下Groovy documentation进一步解释了这一点。