【问题标题】:Groovy method cannot access variable in enclosing scopeGroovy 方法无法访问封闭范围内的变量
【发布时间】:2017-02-08 23:36:25
【问题描述】:

我知道这就是闭包的用途,但下面的内容不应该也适用吗?:

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)

【问题讨论】:

    标签: groovy


    【解决方案1】:

    在 groovy 脚本中(与类相反),您的代码本质上等同于:

    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'
    

    这是的简写:

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

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

    选项 2 - @Field 注释

    详情请见groovy docs on the Field annotation

    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)
      }
    }
    

    这实际上也使脚本中的变量可以“全局”访问。

    【讨论】:

    • 你的第一个代码块已经回答了我很多问题,干得好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-11
    相关资源
    最近更新 更多