我有一个关于在Groovy作用域规则的问题。 在下面的代码片段,我有三个变量, a
具有局部范围, b
有脚本范围, c
应该得到脚本范围以及使用@Field
注解。
#!/usr/bin/groovy
import groovy.transform.Field;
//println org.codehaus.groovy.runtime.InvokerHelper.getVersion()
def a = 42;
b = "Tea"
@Field def c = "Cheese"
void func()
{
// println a // MissingPropertyException
println b // prints "Tea"
println c // prints "Cheese" with groovy 2.1.2, MissingPropertyException with groovy 1.8.6
}
class Main
{
def method()
{
// println a // MissingPropertyException
// println b // MissingPropertyException
// println c // MissingPropertyException with both 1.8.6. and 2.1.2
}
}
func();
new Main().method();
我得到MissingPropertyException
论有评论指出的线。 在例外a
预期,因为该变量具有局部范围。 但我希望b
是访问内部method()
-它不是。 @Field
不会在Groovy 1.8.6做任何事情,但升级后它的作品,所以我想这是一个古老的错误。 尽管如此, c
是内部不可访问method()
与任一版本。
所以我的问题是:
- 为什么我不能访问注释带可变
@Field
内method()
? - 我如何引用脚本变量中
method()
?
当你有一个外部的方法或语句class
Groovy脚本中声明,将创建一个隐含的类。 要回答你的问题:
在你的榜样, func()
可以访问现场c
因为他们是隐含类的成员。 该Main
类是没有,所以它不能。
您需要将引用传递给脚本变量method()
。 一种方式是通过隐含定义binding
对象,通过它可以访问所有的脚本作用域变量。
例:
#!/usr/bin/groovy
import groovy.transform.Field;
//println org.codehaus.groovy.runtime.InvokerHelper.getVersion()
def a = 42;
b = "Tea"
@Field def c = "Cheese"
void func()
{
// println a // MissingPropertyException
println b // prints "Tea"
println c // prints "Cheese" with groovy 2.1.2, MissingPropertyException with groovy 1.8.6
}
class Main
{
def scriptObject
def binding
def method()
{
// println a // MissingPropertyException
println binding.b
println scriptObject.c
}
}
func();
new Main(scriptObject: this, binding: binding).method();
这个脚本和Main
作为同一个文件内两个独立的类生成的。
由于Main
不是一个内部类的脚本类的,它不能看到java.lang.Object c
脚本类场内。
你要么必须与一类明确地把这个包脚本static main( args )
方法(和内部Main
类),或者你需要的脚本类的实例传递给像方法: Main.method( this )
这是诸如此类的事情,上面的脚本生成:
class Script032034034 {
Object c
Script032034034() {
c = 'Cheese'
}
Object run() {
Object a = 42
b = 'Tea'
func()
new Main().method()
}
void func() {
println b
println c
}
}
class Main {
Object method() {
}
}