Groovy方法无法访问封闭作用域中的变量

6za6bjd0  于 2023-10-15  发布在  其他
关注(0)|答案(1)|浏览(143)

我知道这就是闭包的作用,但是下面的代码不也应该工作吗?:

def f = 'foo'
def foo() {
   println(f)
}
foo()

其结果是:

Caught: groovy.lang.MissingPropertyException: No such property: f for class: bar
groovy.lang.MissingPropertyException: No such property: f for class: bar
   at bar.foo(bar.groovy:4)
   at bar.run(bar.groovy:7)
cnjp1d6j

cnjp1d6j1#

在一个groovy脚本中(与class相对),你的代码本质上等同于:

class ScriptName {
  def main(args) {
    new ScriptName().run(args)
  }

  def run(args) {
    def f = 'foo'
    foo()
  }

  def foo() {
    println(f)
  }
}

由groovy为groovy脚本创建的“隐式”封闭类始终存在,但在代码中不可见。上面的内容很明显地解释了为什么foo方法看不到f变量。
你有几个选择

  • 选项1 -绑定 *

详情请参阅groovy docs on script bindings

// put the variable in the script binding
f = 'foo'

(note我们这样做没有def关键字)
这是以下的简写:

binding.setVariable('f', 'foo')

其中脚本绑定对于groovy脚本来说是随处可见的,这使得变量本质上是“全局”的。

  • 选项2 - @字段注解 *

有关详细信息,请参阅Groovy文档中的Field注解。

import groovy.transform.Field
...    
// use the groovy.transform.Field annotation 
@Field f = 'foo'

Field注解是专门用来给予groovy脚本向“隐式”封闭类添加字段的能力的。然后生成的类看起来像下面这样:

class ScriptName {
  def f = 'foo'

  def main(args) {
    new ScriptName().run(args)
  }

  def run(args) {
    foo()
  }

  def foo() {
    println(f)
  }
}

这也基本上使变量在脚本中可以“全局”访问。

相关问题