Domknięcia (closures)
Domknięcie jest to mechanizm, który w Groovym jest wyjątkowo często stosowany. Ma postać bloku kodu objętego nawiasami klamrowymi. Posiada on cechy nie tylko obiektu (można go stworzyć, przesyłać do niego referencje), ale też metody(może przyjmować parametry i zwracać wartości).
Najprostszy przykład domknięcia mógłby wyglądać następująco (być może nie jest zbyt finezyjny, ale póki co sam się tego uczę)
myclosure={textToPrint->print textToPrint}
myclosure("Witaj !")
Powyższy skrypt w pierwszej linii definiuje domknięcie o nazwie myclosure, które pobiera jeden parametr o nazwie "textToPrint". Parametr ten umieszcza się po nawiasie klamrowym, a przed znakiem "->". Jego wartość jest dostępna we wnętrzu domknięcia. Powyższy przykład odwołuje się do otrzymanego parametru i wyświetla jego wartość na konsoli.
W przypadku gdy nasze domknięcie pobiera tylko jeden parametr można skorzystać z oferowanej przez Grooviego skróconej formy definicji i odwołania się do domknięcia. Wartość parametru dostępna jest we wnętrzu domknięcia po odwołaniu się do słowa kluczowego "it".
shortClosure={print it}
shortClosure("Hello Mariusz !!!")
Należy pamiętać że kod domknięcia jest wykonywany dopiero przy odwołaniu się do niego.
Możliwe jest też definiowanie domknięć przyjmujących więcej niż jeden parametr. W takim przypadku przed znakiem -> należy umieścić ich listę:
sumArgClosure={arg1,arg2-> print "SUM="+(arg1+arg2)}
sumArgClosure(5,3)
Powyższy skrypt wyświetli na ekranie napis SUM=8
Bardzo ciekawą własnością domknięć jest to, że istnieje możliwość przesyłania do nich referencji. Jako przykład niech posłuży kod klasy Calculator.
public class Calculator{
def argList=[2,3,4]
public void applyOperation(String operation,c){
print "\nWykonywana operacja to:\n***"+operation+"***"
for (elem in argList){
print "\n"+c(elem)
}
print "\n******"
}
}
def calc=new Calculator()
calc.applyOperation("Mnozeniex3"){(it*3)}
calc.applyOperation("Potegowanie"){(it*it)}
W klasie zdefiniowana jest lista argumentów (argList=[2,3,4]) na której będą wykonywane operacje, oraz jedna metoda, która jako swój parametr przyjmuje domknięcie i tekstową nazwę operacji którą ma wykonać(chociaż znaczenie tego parametru jest mało istotne - wykorzystywane jest tylko do wyświetlenia komentarza). We wnętrzu metody zdefiniowana została pętla która przechodzi po wszystkich elementach listy argumentów, a następnie dla każdego z nich wykonuje domknięcie, przysłane do metody w parametrze :
for (elem in argList){
print "\n"+ c(elem)
}
print "\n******"
}
Wywołanie w.w. metody ma postać:
calc.applyOperation("Mnozeniex3"){(it*3)}
calc.applyOperation("Potegowanie"){(it*it)}
Za każdym razem na argumentach kalkulatora zostanie wywołana operacja zdefiniowana w domknięciu. Należy zwrócić uwagę na pewne udogodnienie, mianowicie definiowanie domknięcia przesyłanego w parametrze może wystąpić poza argumentami funkcji (chociaż notacja tradycyjna, po przecinku też jest dopuszczalna).