Groovy中的全局常量

jus*_*ovy 46 groovy global-variables

通常需要在脚本顶部声明常量,这些常量可以在脚本中的任何其他位置引用.在Groovy中,似乎如果使用final声明一个常量,那么它在子范围内是不可访问的.这个非常基本和常见的要求是什么解决方案?我现在的解决方法是创建一个未绑定的变量,但这不是常量,也不优雅.

ata*_*lor 79

Groovy并没有真正的全球范围.如果你有一个没有声明类的groovy脚本,它会隐藏在一个带有脚本名称的类中.因此,顶级范围内的最终变量实际上只是隐式类的字段.例如:

// foo.groovy
final MYCONSTANT = "foobar"
println MYCONSTANT

class Helper {
    def hello() { println MYCONSTANT }  // won't work
}
new Helper().hello()
Run Code Online (Sandbox Code Playgroud)

或多或少相当于:

class foo {
    def run() {
        final MYCONSTANT = "foobar"
        println MYCONSTANT
        new Helper().hello()
    }
    static main(args) {
        new foo().run()
    }
}

class Helper {
    def hello() { println MYCONSTANT }  // won't work
}
Run Code Online (Sandbox Code Playgroud)

很容易理解为什么它不能扩展出来.一个简单的解决方法是在一个名为Constants的虚拟类中声明你的"全局变量",然后只对它进行静态导入.它甚至可以在一个脚本中运行.例:

import static Constants.*

class Constants {
    static final MYCONSTANT = "foobar"
}

println MYCONSTANT

class Helper {
    def hello() { println MYCONSTANT } // works!
}
new Helper().hello()
Run Code Online (Sandbox Code Playgroud)

编辑:

此外,脚本有点特殊情况.如果你声明一个没有def或没有任何修饰符的变量final,(即只是使用它)它会进入一个脚本范围的绑定.所以在这种情况下:

CONSTANT = "foobar"
println "foobar"
Run Code Online (Sandbox Code Playgroud)

CONSTANT在脚本范围内绑定,但在:

final CONSTANT = "foobar"
println "foobar"
Run Code Online (Sandbox Code Playgroud)

CONSTANT是脚本run()方法中的局部变量.有关这方面的更多信息,请访问https://web-beta.archive.org/web/20150108090004/http://groovy.codehaus.org/Scoping+and+the+Semantics+of+%22def%22

  • @Esko每种类型的常量应该是一个枚举?甚至像GRAVITY或PI?O_O (7认同)
  • @Esko我试图指出你最初的陈述并不适用于所有常量 (2认同)

bma*_*pin 22

在Groovy 1.8+中,您可以使用@Field注释实现此目的:

import groovy.transform.Field

@Field final String MY_CONSTANT = 'constant'

def printConstant() { println MY_CONSTANT }

printConstant()
Run Code Online (Sandbox Code Playgroud)

  • @Anentropic:不要错过“ import groovy.transform.Field”上方的导入 (2认同)