Uzávery v Groovy

1. Prehľad

V tomto úvodnom výučbe sa pozrieme na koncepciu uzáverov v Groovy, čo je kľúčová vlastnosť tohto dynamického a výkonného jazyka JVM.

Mnoho ďalších jazykov, vrátane Javascript a Python, podporuje koncept uzávierok. Charakteristiky a fungovanie uzávierok sa však v jednotlivých jazykoch líšia.

Dotkneme sa kľúčových aspektov uzáverov Groovy a ukážeme si príklady ich použitia pozdĺž cesty.

2. Čo je uzávierka?

Uzávierka je anonymný blok kódu. V Groovy je to inštancia Uzavretie trieda. Uzávery môžu trvať 0 alebo viac parametrov a vždy vrátia hodnotu.

Uzávierka navyše môže pristupovať k okolitým premenným mimo jej rozsahu a používať ich - spolu so svojimi miestnymi premennými - počas vykonávania.

Ďalej môžeme premennej priradiť uzáver alebo ho odovzdať ako parameter metóde. Uzávierka preto poskytuje funkčnosť oneskoreného vykonania.

3. Vyhlásenie o ukončení

Groovy Closure obsahuje parametre, šípku -> a kód, ktorý sa má vykonať. Parametre sú voliteľné a ak sú poskytnuté, sú oddelené čiarkou.

3.1. Základné vyhlásenie

def printWelcome = {println "Vitajte na uzávierkach!" }

Tu uzávierka tlačVítajte vypíše vyhlásenie, keď je vyvolané. Poďme si teraz napísať rýchly príklad unárneho uzavretia:

def print = {name -> println name}

Tu uzávierka tlačiť trvá jeden parameter - názov - a po vyvolaní ju vytlačí.

Pretože definícia uzávery vyzerá podobne ako metóda, porovnajme ich:

def formatToLowerCase (name) {return name.toLowerCase ()} def formatToLowerCaseClosure = {name -> return name.toLowerCase ()} 

Tu sa spôsob a zodpovedajúce uzavretie správajú podobne. Medzi uzáverom a metódou však existujú jemné rozdiely, o ktorých si povieme neskôr v časti Uzávery vs metódy.

3.2. Exekúcia

Uzávierku môžeme vykonať dvoma spôsobmi - môžeme ju vyvolať, akoby to bola iná metóda, alebo môžeme použiť príkaz hovor metóda.

Napríklad ako bežná metóda:

print ("Hello! Closure") formatToLowerCaseClosure ("Hello! Closure") 

A vykonávanie s hovor metóda:

print.call ("Hello! Closure") formatToLowerCaseClosure.call ("Hello! Closure")

4. Parametre

Parametre uzáverov Groovy sú podobné ako pri bežných metódach.

4.1. Implicitný parameter

Môžeme definovať unárne uzavretie bez parametra, pretože ak parametre nie sú definované, Groovy predpokladá implicitný parameter s názvom „to ”:

def greet = {return "Dobrý deň! $ {it}"} potvrdiť pozdrav ("Alex") == "Dobrý deň! Alex"

4.2. Viaceré parametre

Tu je uzávierka, ktorá berie dva parametre a vráti výsledok ich vynásobenia:

def znásobiť = {x, y -> vrátiť x * y} uplatniť vynásobiť (2, 4) == 8

4.3. Typy parametrov

V doterajších príkladoch nebol poskytnutý žiadny typ s našimi parametrami. Môžeme tiež nastaviť typ parametrov uzávierky. Napíšme napríklad znásobiť metóda na zváženie ďalších operácií:

def vypočítať = {int x, int y, reťazcová operácia -> def výsledok = 0 prepínač (operácia) {prípad "PRIDAŤ": výsledok = x + y prípad prerušenia "SUB": výsledok = xy prípad prerušenia "MUL": výsledok = x * y prípad prerušenia "DIV": result = x / y break} návratový výsledok} uplatniť výpočet (12, 4, "PRIDAŤ") == 16 uplatniť výpočet (43, 8, "DIV") == 5,375

4.4. Varargs

Môžeme deklarovať variabilný počet argumentov v závere, podobne ako pri bežných metódach. Napríklad:

def addAll = {int ... args -> return args.sum ()} uplatniť addAll (12, 10, 14) == 36

5. Uzávierka ako argument

Môžeme prejsť a Uzavretie ako argument k bežnej Groovy metóde. To umožňuje metóde zavolať našu uzávierku na dokončenie jej úlohy, čo nám umožňuje prispôsobiť jej správanie.

Poďme diskutovať o jednoduchom prípade použitia: výpočte objemu pravidelných čísel.

V tomto príklade je objem definovaný ako plocha vynásobená výškou. Výpočet plochy sa však môže líšiť pre rôzne tvary.

Preto napíšeme objem metóda, ktorá sa uzatvára areaCalculator ako argument a pri vyvolaní prejdeme implementáciou výpočtu plochy:

def volume (Closure areaCalculator, int ... Dimensions) {if (Dimensions.size () == 3) {return areaCalculator (Dimensions [0], Dimensions [1]) * Dimensions [2]} else if (Dimensions.size () == 2) {return areaCalculator (Dimensions [0]) * Dimensions [1]} else if (Dimensions.size () == 1) {return areaCalculator (Dimensions [0]) * Dimensions [0]}} assert objem ({l, b -> návrat l * b}, 12, 6, 10) == 720 

Nájdeme objem kužeľa rovnakou metódou:

potvrdiť objem ({radius -> return Math.PI * radius * radius / 3}, 5, 10) == Math.PI * 250

6. Vnorené uzávery

Môžeme vyhlásiť a vyvolať uzávery vo vnútri uzáveru.

Napríklad pridajme už zaznamenanú schopnosť protokolovania vypočítať uzávierka:

def vypočítať = {int x, int y, operácia s reťazcom -> def log = {println "Vykonávam $ it"} def result = 0 switch (operation) {case "ADD": log ("Addition") result = x + y prípad prerušenia "SUB": výsledok protokolu ("Odčítanie") = xy prípad prerušenia "MUL": výsledok protokolu ("Násobenie") výsledok = x * y prípad prerušenia "DIV": výsledok protokolu ("Rozdelenie") = výsledok x / y } vrátiť výsledok}

7. Lenivé hodnotenie strún

Groovy Strings sa zvyčajne hodnotia a interpolujú v čase vytvorenia. Napríklad:

def name = "Samwell" def welcomeMsg = "Vitajte! $ name" tvrdiť welcomeMsg == "Vitajte! Samwell"

Aj keď upravíme hodnotu názov premenná, welcomeMsg sa nezmení:

name = "Tarly" tvrdí welcomeMsg! = "Vitajte! Tarly"

Uzatváracia interpolácia nám umožňuje poskytnúť lenivé vyhodnotenie Strings, prepočítané z aktuálnych hodnôt okolo nich. Napríklad:

def fullName = "Tarly Samson" def greetStr = "Dobrý deň! $ {-> fullName}" potvrdiť greetStr == "Dobrý deň! Tarly Samson"

Iba tentoraz zmena premennej ovplyvní aj hodnotu interpolovaného reťazca:

fullName = "Jon Smith" tvrdí greetStr == "Ahoj! Jon Smith"

8. Uzávery v zbierkach

Groovy Collections používajú uzávery v mnohých svojich API. Napríklad definujme zoznam položiek a vytlačme ich pomocou unárneho uzáveru každý, ktorý má implicitný parameter:

def list = [10, 11, 12, 13, 14, true, false, "BUNTHER"] list.each {println it} uplatniť [13, 14] == list.findAll {it instanceof Integer && it> = 13}

Na základe niektorých kritérií bude často potrebné vytvoriť zoznam z mapy. Napríklad:

def map = [1:10, 2:30, 4: 5] uplatniť [10, 60, 20] == map.collect {it.key * it.value} 

9. Uzávery vs metódy

Doteraz sme videli syntax, vykonávanie a parametre uzávierok, ktoré sú dosť podobné metódam. Poďme si teraz porovnať uzávery s metódami.

Na rozdiel od bežnej metódy Groovy:

  • Môžeme prejsť a Uzavretie ako argument k metóde
  • Unárne uzávery môžu používať implicitné to parameter
  • Môžeme priradiť a Uzavretie do premennej a spustiť ju neskôr, buď ako metódu, alebo pomocou hovor
  • Groovy určuje návratový typ uzáverov za behu
  • Môžeme vyhlásiť a vyvolať uzávery vo vnútri uzáveru
  • Uzávery vždy vrátia hodnotu

Preto majú uzávery výhody oproti bežným metódam a sú silnou vlastnosťou Groovy.

10. Záver

V tomto článku sme videli, ako vytvoriť uzávery v Groovy, a preskúmali sme, ako sa používajú.

Uzávery poskytujú efektívny spôsob, ako vložiť funkčnosť do objektov a metódy na oneskorené vykonanie.

Testy kódu a jednotiek z tohto článku sú ako vždy k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found