Groovy作用域-如何访问方法中的脚本变量
我有一个关于Groovy中的作用域规则的问题。在下面的代码片段中,我有三个变量,Groovy作用域-如何访问方法中的脚本变量,groovy,scope,Groovy,Scope,我有一个关于Groovy中的作用域规则的问题。在下面的代码片段中,我有三个变量,a有局部作用域,b有脚本作用域,c也应该使用@字段注释获得脚本作用域 #!/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()
a
有局部作用域,b
有脚本作用域,c
也应该使用@字段
注释获得脚本作用域
#!/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
s。a
上的异常是预期的,因为该变量具有局部范围。但是我希望b
可以在method()中访问,但事实并非如此。
@Field
在groovy 1.8.6中没有做任何事情,尽管升级后它可以工作,所以我想这是一个老错误。尽管如此,c
在method()
的任何版本中都是不可访问的
因此,我的问题是:
为什么我不能访问内部带有@Field
注释的变量
method()
李>
如何引用method()
中的脚本变量
当groovy脚本中的类
声明之外有方法或语句时,将创建一个隐式类。回答您的问题:
在您的示例中,func()
可以访问字段c
,因为它们都是隐式类的成员。Main
类不是,因此它不能
您需要将对脚本变量的引用传递给method()
。一种方法是传递隐式定义的绑定
对象,通过该对象可以访问所有脚本范围变量
例如:
#!/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() {
}
}
感谢生成的代码片段,这对我的理解有很大帮助。我的误解是,我认为Main将是Script032034034的一个子类。在您提供的代码中,func()
如何“查看”b
?b
也是Script类的一个属性吗?非常确定您的意思是将那些scriptObject和binding参数传递给构造函数,一个新的Main(scriptObject:this,binding:binding.method())