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

lap*_*ots 4 groovy

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

例如

def s = "12345"

class MyClass {
    static def method() {
        println s
    }
}
Run Code Online (Sandbox Code Playgroud)

因为这种方式失败了,错误

You attempted to reference a variable in the binding or an instance variable from a static context
Run Code Online (Sandbox Code Playgroud)

这是预期的.

tyl*_*wal 9

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

Groovy范围 - 如何在方法中访问脚本变量

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

传递脚本的实例

import groovy.transform.Field

@Field def s = "12345"

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

assert MyClass.method(this) == "12345"
Run Code Online (Sandbox Code Playgroud)

传递脚本的绑定

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

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

assert MyClass.method(binding) == "12345"
Run Code Online (Sandbox Code Playgroud)

  • 那么基本上与基本的“java”方法一样吗?我认为 Groovy 允许它以某种方式做,因为它更灵活。 (2认同)

Emm*_*osa 5

好吧,问题在于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
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

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

注意:删除def不会解决此问题。

最好的选择是将“全局变量”放入类中,可能作为静态属性,如下所示:

class Global {
    static Object S = "12345"
}

class MyClass {
    static def method() {
        println Global.S
    }
}
Run Code Online (Sandbox Code Playgroud)