Groovy method cannot access variable in enclosing scope

前端 未结 1 659
太阳男子
太阳男子 2020-12-18 07:26

I know that this is what closures are for, but shouldn\'t the below work as well?:

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

It res

相关标签:
1条回答
  • 2020-12-18 08:22

    In a groovy script (as opposed to class), your code is essentially equivalent to:

    class ScriptName {
      def main(args) {
        new ScriptName().run(args)
      }
    
      def run(args) {
        def f = 'foo'
        foo()
      }
    
      def foo() {
        println(f)
      }
    }
    

    the 'implicit' enclosing class created by groovy for groovy scripts is always present but not visible in your code. The above makes it obvious why the foo method does not see the f variable.

    You have a couple of options

    option 1 - binding

    See the groovy docs on script bindings for details.

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

    this is shorthand for:

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

    where the script binding is visible everywhere for groovy scripts and this makes the variable essentially 'global'.

    option 2 - @Field annotation

    See groovy docs on the Field annotation for details.

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

    the Field annotation is specifically there to give groovy scripts the ability to add fields to the 'implicit' enclosing class. The generated class would then look something like the following:

    class ScriptName {
      def f = 'foo'
    
      def main(args) {
        new ScriptName().run(args)
      }
    
      def run(args) {
        foo()
      }
    
      def foo() {
        println(f)
      }
    }
    

    which also essentially makes the variable accessible 'globally' in the script.

    0 讨论(0)
提交回复
热议问题