Статьи

Закрытия в Groovy

Суд-Closure Самым простым объяснением замыкания в Groovy является то, что оно является анонимной функцией.

1
2
def closure = { println "I am a closure" }
closure() // Prints I am a closure

Итак, первое, что нужно сказать, это то, что закрытие не печатается, когда закрытие определено, а только когда оно вызывается Закрытия облегчают отложенное выполнение. Также возможно передать параметры в замыкание

1
2
def closureWithParameters = {x, y -> print(x  + " and " + y)}
closureWithParameters("Hello dudes", "Hello Mega Dude"// Prints Hello dudes and Hello Mega Dude

Когда замыкание имеет только один параметр, нам даже не нужен ->, мы можем просто использовать неявную переменную it .

1
2
def closureWithParameters = { println it }
closureWithParameter("Hello dude"// Prints Hello dude

Сейчас, сейчас, сейчас детишки. Замыкания существуют не только в Groovy, они существуют во многих языках, и одна из их особенностей, о которых люди иногда забывают, состоит в том, что они содержат представление лексической среды функции. В английском это означает, что они получают снимок контекста, в котором они определены, и только они могут получить доступ к этому снимку и изменить его. В JavaScript мы можем сделать что-то вроде этого:

1
2
3
4
5
6
7
function outerFuntion () {
    var counter = 1;
    function innerFunction() {
        alert("Counter=" + counter++);
    }  
    return innerFunction;
}

Несмотря на то, что счетчик определен в externalFunction () как локальная переменная, он считается находящимся в лексической среде innerFunction (), поэтому он может получить к нему доступ. Когда innerFunction () возвращается в качестве замыкания, он получает свое собственное значение, к которому имеет доступ только он. Так что, если мы должны были сделать это:

1
2
var myClosure = outerFuntion();  // myFunc is now a pointer to the innerFunction closure.
myClosure();  // Executes Counter=1;

Сначала выполняется externalFunction (), и он возвращает замыкание innerFunction. Переменная присваивается этому закрытию. Теперь, сейчас, сейчас, обратите внимание, что ключевое слово здесь «вернулся». innerFunction () возвращается , он не выполняется. Итак, снова мы видим задержку исполнения, характерную для замыканий. Каждый раз, когда мы выполняем замыкание, счетчик увеличивается.

1
2
3
4
5
myClosure();  // Executes Counter=2;
myClosure();  // Executes Counter=3;
myClosure();  // Executes Counter=4;
myClosure();  // Executes Counter=5;
myClosure();  // Executes Counter=6;

Таким образом, закрытие имеет состояние, которое оно запоминает через вызовы. Это состояние начинается как моментальный снимок контекста, в котором определена функция, и это то, что могут изменить только их закрытие. Так что да, это ключевой момент закрытия. Это особый вид объекта, который объединяет две вещи: функцию и среду, в которой эта функция была создана. Среда состоит из переменных, которые находились в области действия во время создания замыкания. Итак, вернемся к Groovy. Тот же пример будет выглядеть так:

1
2
3
4
5
6
def outerFunction () {
    def counter = 1;
    return {
        print "Counter=" + counter++
    }
}
1
2
3
4
5
6
7
8
def myClosure = outerFunction()
 
myClosure();  // executes 1
myClosure();  // executes 2
myClosure();  // executes 3
myClosure();  // executes 4
myClosure();  // executes 5
myClosure();  // executes 6

Это очень похоже на пример JavaScript. Слово def используется вместо функции . Мы также просто используем тот факт, что вам не нужно использовать функцию слова в Groovy, когда вы хотите определить анонимную функцию. Если бы мы хотели сделать внутреннюю функцию анонимной в версии JavaScript, мы могли бы сделать:

01
02
03
04
05
06
07
08
09
10
function outerFuntion () {
    var counter = 1;
    return function () {
        alert("Counter=" + counter++);
    };
}
 
var myClosure = outerFuntion();  // myFunc is now a pointer to the innerFunction closure.
myClosure();  // Executes Counter=1;
myClosure();  // Executes Counter=2;

Но все равно придется использовать слово function, нам просто не нужно давать ему имя. Хорошо, так что до следующего раза береги себя.

Ссылка: Закрытие в Groovy от нашего партнера JCG Алекса Стейвли в блоге Tech Blog в Дублине