MissingMethodException при вызове закрытия Groovy внутри закрытия - PullRequest
0 голосов
/ 17 февраля 2020

У меня есть сценарий groovy, который выглядит примерно так:

def clouser = {
    def clouserOne = { _argsA  -> 
        def clouserTwo = { _argsB ->
            // Do Something with _argsA and _argsB
            println(_argsA)
            println(_argsB)
        }
    }
} 

при вызове этого

clouser().clouserOne("A").clouserTwo("B")

Я получаю сообщение об ошибке

groovy.lang.MissingMethodException: No signature of method: Script1.clouserOne() is applicable for argument types: (String) values: [A]
    at Script1.run(Script1.groovy:11)

Как правильно определить этот тип закрытия внутри закрытия? И как правильно это назвать?

Ответы [ 2 ]

0 голосов
/ 17 февраля 2020

После некоторого прочтения я наткнулся на более сложное замыкание замыкания, которое будет принимать замыкание и выполняться внутри замыкания. Например:

someClouser = {_args -> _args }

clouser = {
    clouserOne = { String _argOne -> 
        clouserTwo = { String _argTwo, Closure c={any()} -> 
            print "Use _argOne: ${_argOne} and _argTwo : ${_argTwo} and invoke passed clouser ${c.call()} this way" 
        }
    } 
}.call()

и его можно вызывать или использовать как

clouser.clouserOne("IMAGE").clouserTwo("INSIDE") ​{ 
     someClouser "Hello World" 
}​​​

Результат будет

Use _argOne: IMAGE and _argTwo : INSIDE and invoke passed clouser Hello World this way
0 голосов
/ 17 февраля 2020

Проблема исходного кода в том, что вы определяете только некоторые локальные переменные, которые никогда не используются. Вместо этого назначенное закрытие возвращается напрямую.

Чтобы ваш исходный код работал, вы можете позвонить:

closure()("A")("B")

(Каждый закрывающий вызов возвращает следующее закрытие, и вы просто объединяете вызовы; конечно, нет необходимости иметь def clouserXXX там).

Если вы пропустите only def, вы создадите "глобальные переменные", и это, скорее всего, не то, что вы хотите.

Если вы хотите, чтобы имена были там, вы должны вернуть что-то с именами. Один простой пример - использование карт в качестве возврата. Например:

def closure = { ->
    [closureOne: { _argsA  -> 
        [closureTwo: { _argsB ->
            println(_argsA)
            println(_argsB)
        }]
    }]
} 

closure().closureOne("A").closureTwo("B")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...