Groovy中的全局常数

Groovy中的全局常数,groovy,global-variables,Groovy,Global Variables,通常需要在脚本顶部声明常量,这些常量可以在脚本中的任何其他位置引用。在Groovy中,如果您使用final声明一个常量,那么它在子作用域中是不可访问的。对于这个非常基本和常见的需求,解决方案是什么?我现在的解决方法是创建一个未绑定的变量,但这不是一个常量,也不优雅。Groovy实际上没有全局范围。当您有一个没有声明类的groovy脚本时,它会隐式地陷入一个带有脚本名称的类中。所以顶级作用域中的最终变量实际上只是隐式类的字段。例如: // foo.groovy final MYCONSTANT =

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

Groovy实际上没有全局范围。当您有一个没有声明类的groovy脚本时,它会隐式地陷入一个带有脚本名称的类中。所以顶级作用域中的最终变量实际上只是隐式类的字段。例如:

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

class Helper {
    def hello() { println MYCONSTANT }  // won't work
}
new Helper().hello()
大致相当于:

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
}
很容易看出它为什么不起作用。一个简单的解决方法是在一个名为例如常量的伪类中声明“globals”,然后对其进行静态导入。它甚至可以在一个脚本中运行。例如:

import static Constants.*

class Constants {
    static final MYCONSTANT = "foobar"
}

println MYCONSTANT

class Helper {
    def hello() { println MYCONSTANT } // works!
}
new Helper().hello()
编辑:

另外,脚本有点特殊。如果您声明的变量不带
def
或任何修饰符,如
final
,(即仅使用它),它将进入脚本范围的绑定。因此,在这种情况下:

CONSTANT = "foobar"
println "foobar"
常量位于脚本范围的绑定中,但位于:

final CONSTANT = "foobar"
println "foobar"

常量是脚本的
run()
方法中的局部变量。有关这方面的更多信息,请参见Groovy 1.8+中的

,您可以使用:


添加全局应用程序级常量的另一种有效方法是 在合适的包中声明一个接口作为

interface applicationConstants {
//All constants goes here.
    static final float PI = 3.14 
    String ADMIN_USER = "ADMIN"
    Map languages = [
        "en":   "English",
        "hi":   "Hindi",
        "mr":   "Marathi"

    ]
// Like above you can declare all application level code constants here.

}
在任何类中使用常数,如下所示

 import packageNameContainingInterface.applicationConstants // import statement.
 def adminUser = applicationConstants.ADMIN_USER
 println adminUser

我个人不会这么做,但从技术上讲你可以这么做

Object.metaclass.MYCONSTANT='foobar'


那么每个对象都有它

常量应该是Java 1.5+世界中的枚举…:)@Esko每种类型的常量都应该是枚举?甚至像重力或π?O_o@tim_yates:否,枚举应包含彼此相关的所有常量。在您的示例中,类似于
CelestialObjectAttributes.GRAVITY
mathematicsconstants.PI
。它们也可以导入,这样您就不必重复枚举的名称,并且枚举始终是VM(或类加载器)全局的,这使它们成为旧学派全局常量的完美替代品。@Esko我试图指出您最初的陈述并非完全正确constants@tim_yates:那你为什么不这么说?尽管如此,也许一些澄清,如“全局常量应表示为枚举…”会很好。@Anentropic:不要错过上面的导入“import groovy.transform.Field”
 import packageNameContainingInterface.applicationConstants // import statement.
 def adminUser = applicationConstants.ADMIN_USER
 println adminUser