2017-02-08 1 views
2

Я знаю, что это то, что затворы предназначены для, но должны не ниже работы, а также ?:Groovy метод не может получить доступ к переменной в области видимости

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) 

ответ

4

в заводных сценариях (в отличие от класса), код по существу эквивалентен:

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

где скрипт связывания виден везде заводных сценарии, и это делает переменные по существу «глобальным».

вариант 2 - @Field аннотацию

См groovy docs on the Field annotation подробности.

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

Поле аннотаций специально там, чтобы дать Groovy скрипты возможность добавлять поля к «неявной» вмещающих класса. Сгенерированный класс будет выглядеть примерно так:

class ScriptName { 
    def f = 'foo' 

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

    def run(args) { 
    foo() 
    } 

    def foo() { 
    println(f) 
    } 
} 

, который также по существу делает переменную доступной «глобально» в сценарии.