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