Introduktion til Groovy Language

1. Oversigt

Groovy er et dynamisk script-sprog til JVM. Det kompileres til bytecode og blandes problemfrit med Java-kode og biblioteker.

I denne artikel vil vi se på nogle af de væsentlige funktioner i Groovy, herunder grundlæggende syntaks, kontrolstrukturer og samlinger.

Derefter vil vi se på nogle af de vigtigste funktioner, der gør det til et attraktivt sprog, herunder null sikkerhed, implicit sandhed, operatorer og strenge.

2. Miljø

Hvis vi vil bruge Groovy i Maven-projekter, skal vi tilføje følgende til pom.xml:

  // ... org.codehaus.gmavenplus gmavenplus-plugin 1.5 // ... org.codehaus.groovy groovy-all 2.4.10 

Det seneste Maven-plugin kan findes her og den nyeste version af groovy-all her.

3. Grundlæggende funktioner

Der er mange nyttige funktioner i Groovy. Lad os nu se på de grundlæggende byggesten i sproget, og hvordan det adskiller sig fra Java.

Lad os nu se på de grundlæggende byggesten i sproget, og hvordan det adskiller sig fra Java.

3.1. Dynamisk typning

En af de vigtigste funktioner i Groovy er dens understøttelse af dynamisk typing.

Typedefinitioner er valgfri, og faktiske typer bestemmes ved kørselstid. Lad os se på disse to klasser:

klasse Duck {String getName () {'Duck'}} klasse Cat {String getName () {'Cat'}} 

Disse to klasser definerer det samme getName metode, men den er ikke defineret eksplicit i en kontrakt.

Forestil dig nu, at vi har en liste over genstande, der indeholder ænder og katte, der har getName metode. Med Groovy kan vi gøre følgende:

Duck duck = new Duck () Cat cat = new Cat () def list = [duck, cat] list.each {obj -> println obj.getName ()}

Koden kompileres, og output af koden ovenfor ville være:

Andekat

3.2. Implicit sandhedskonvertering

Som i JavaScript evaluerer Groovy hvert objekt til en boolsk, hvis det kræves, f.eks. når du bruger den i en hvis erklæring eller når negerer værdien:

hvis ("hej") {...} hvis (15) {...} hvis (someObject) {...}

Der er et par enkle regler at huske på denne konvertering:

  • Ikke-tom Samlinger, arrays, maps evaluere til rigtigt
  • Matcher med mindst en kamp evalueres til rigtigt
  • Iteratorer og Tællinger med yderligere elementer tvinges til rigtigt
  • Ikke-tom Strenge, GStrings og CharSequences, tvinges til rigtigt
  • Ikke-nul tal evalueres til rigtigt
  • Ikke-null objektreferencer tvinges til rigtigt

Hvis vi ønsker at tilpasse den implicitte sandhedskonvertering, kan vi definere vores asBoolean () metode.

3.3. Import

Nogle pakker importeres som standard, og vi behøver ikke at importere dem eksplicit:

import java.lang. * import java.util. * import java.io. * import java.net. * import groovy.lang. * import groovy.util. * import java.math.BigInteger import java.math.BigDecimal

4. AST Transforms

AST (Abstrakt syntaks træ) transformer giver os mulighed for at tilslutte sig Groovy-kompileringsprocessen og tilpasse den til vores behov. Dette gøres på kompileringstidspunktet, så der er ingen præstationsstraffe, når applikationen køres. Vi kan oprette vores AST-transformationer, men vi kan også bruge de indbyggede.

Vi kan skabe vores transformationer, eller vi kan drage fordel af de indbyggede.

Lad os se på nogle kommentarer, der er værd at vide.

4.1. Kommentar TypeKontrolleret

Denne kommentar bruges til at tvinge kompilatoren til at foretage streng typekontrol af kommenterede kodestykker. Typekontrolmekanismen er udvidelig, så vi kan endda levere endnu strengere typekontrol end tilgængelig i Java, når det ønskes.

Lad os se på eksemplet nedenfor:

klasse Univers {@TypeChecked int svar () {"toogtredive"}}

Hvis vi forsøger at kompilere denne kode, observerer vi følgende fejl:

[Statisk typekontrol] - Kan ikke returnere værdien af ​​typen java.lang.Streng på metode, der returnerer type int

Det @TypeChecked annotering kan anvendes på klasser og metoder.

4.2. Kommentar CompileStatic

Denne kommentar giver kompilatoren mulighed for at udføre kompileringstidskontrol, som det gøres med Java-kode. Derefter udfører compileren en statisk kompilering og omgår dermed Groovy metaobject-protokollen.

Når en klasse er kommenteret, vil alle metoder, egenskaber, filer, indre klasser osv. I den kommenterede klasse blive typekontrolleret. Når en metode er kommenteret, anvendes statisk kompilering kun på de emner (lukninger og anonyme indre klasser), der er lukket af denne metode.

5. Egenskaber

I Groovy kan vi oprette POGO'er (Plain Old Groovy Objects), der fungerer på samme måde som POJO'er i Java, selvom de er mere kompakte, fordi getters og setter genereres automatisk til offentlige ejendomme under kompilering. Det er vigtigt at huske, at de kun genereres, hvis de ikke allerede er defineret.

Dette giver os fleksibiliteten ved at definere attributter som åbne felter, mens vi bevarer evnen til at tilsidesætte adfærden, når vi indstiller eller henter værdierne.

Overvej dette objekt:

klasse Person {String name String lastName}

Da standardområdet for klasser, felter og metoder er offentlig - dette er en offentlig klasse, og de to felter er offentlige.

Compileren konverterer disse til private felter og tilføjer getName (), sætnavn (), getLastName () og setLasfName () metoder. Hvis vi definerer setter og getter for et bestemt felt opretter kompilatoren ikke en offentlig metode.

5.1. Genvejsnotationer

Groovy tilbyder en genvejsnotation for at hente og indstille egenskaber. I stedet for Java-måde at kalde getters og settere på, kan vi bruge en feltlignende adgangsnotation:

resourceGroup.getResourcePrototype (). getName () == SERVER_TYPE_NAME resourceGroup.resourcePrototype.name == SERVER_TYPE_NAME resourcePrototype.setName ("noget") resourcePrototype.name = "noget"

6. Operatører

Lad os nu se på nye operatører tilføjet oven på dem, der er kendt fra almindelig Java.

6.1. Null-Safe Dereference

Den mest populære er den null-safe dereference-operatør “?” hvilket giver os mulighed for at undgå en NullPointerException når du ringer til en metode eller får adgang til en ejendom af en nul objekt. Det er især nyttigt i kædede opkald, hvor en nul værdi kan forekomme på et eller andet tidspunkt i kæden.

For eksempel kan vi trygt ringe:

Strengnavn = person? .Organisation? .Forælder? .Navn

I eksemplet ovenfor, hvis en person, person. organisation, eller organisation. forælder er nul, derefter nul returneres.

6.2. Elvis operatør

Elvis-operatøren “?:”Lader os kondensere ternære udtryk. Disse to er ækvivalente:

Strengnavn = person.navn?: Standardnavn

og

Strengnavn = person.navn? person.navn: standardnavn

De tildeler begge værdien af person.navn til navnevariablen, hvis den er Groovy sandt (i dette tilfælde ikke nul og har en ikke-nul længde).

6.3. Rumskibsoperatør

Rumskibsoperatøren “” er en relationsoperatør, der fungerer som Java sammenligne med() der sammenligner to objekter og returnerer -1, 0 eller +1 afhængigt af værdierne for begge argumenter.

Hvis venstre argument er større end højre, returnerer operatøren 1. Hvis venstre argument er mindre end højre, returnerer operatøren −1. Hvis argumenterne er ens, returneres 0.

Den største fordel ved at bruge sammenligningsoperatørerne er den glatte håndtering af nul sådan at x y vil aldrig smide en NullPointerException:

println 5 null

Ovenstående eksempel udskriver 1 som et resultat.

7. Strenge

Der er flere måder at udtrykke strengbogstaver på. Den fremgangsmåde, der anvendes i Java (dobbelt citerede strenge) understøttes, men det er også tilladt at bruge enkelte citater, når det foretrækkes.

Flerstrengede strenge, undertiden kaldet heredocs på andre sprog, understøttes også ved hjælp af tredobbelte citater (enten enkelt eller dobbelt).

Multi-line strenge, undertiden kaldet heredocs på andre sprog, understøttes også ved hjælp af tredobbelte citater (enten enkelt eller dobbelt).

Strenge defineret med dobbelt anførselstegn understøtter interpolering ved hjælp af ${} syntaks:

def name = "Bill Gates" def greeting = "Hej, $ {name}"

Faktisk kan ethvert udtryk placeres inde i ${}:

def name = "Bill Gates" def greeting = "Hej, $ {name.toUpperCase ()}"

En streng med dobbelt anførselstegn kaldes en GString, hvis den indeholder et udtryk ${}, ellers er det en almindelig Snor objekt.

Koden nedenfor kører uden at fejle testen:

def a = "hej" hævder a.class.name == 'java.lang.String' def b = 'hej' hævder b.class.name == 'java.lang.String' def c = "$ {b} "hævde c.class.name == 'org.codehaus.groovy.runtime.GStringImpl'

8. Samlinger og kort

Lad os se på, hvordan nogle grundlæggende datastrukturer håndteres.

8.1. Lister

Her er en kode, der kan tilføjes et par elementer til en ny forekomst af ArrayList i Java:

Liste liste = ny ArrayList (); list.add ("Hej"); list.add ("Verden");

Og her er den samme operation i Groovy:

Liste liste = ['Hej', 'Verden']

Lister er som standard af typen java.util.ArrayList og kan også erklæres eksplicit ved at ringe til den tilsvarende konstruktør.

Der er ikke en separat syntaks for en Sæt, men vi kan bruge typen tvang for det. Brug enten:

Indstil hilsen = ['Hej', 'Verden']

eller:

def greeting = ['Hello', 'World'] som Set

8.2. Kort

Syntaksen for en Kort er ens, omend lidt mere detaljeret, fordi vi skal være i stand til at specificere nøgler og værdier afgrænset med kolon:

def key = 'Key3' def aMap = ['Key1': 'Value 1', Key2: 'Value 2', (key): 'Another value']

Efter denne initialisering får vi en ny LinkedHashMap med posterne: Key1 -> Value1, Key2 -> Value 2, Key3 -> Another Value.

Vi kan få adgang til poster på kortet på mange måder:

println aMap ['Key1'] println aMap [key] println aMap.Key1

9. Kontrolstrukturer

9.1. Betingelser: hvis ellers

Groovy understøtter den betingede hvis ellers syntaks som forventet:

hvis (...) {// ...} ellers hvis (...) {// ...} ellers {// ...} 

9.2. Betingelser: afbryderkasse

Det kontakt Erklæring er bagudkompatibel med Java-kode, så vi kan falde igennem sager, der deler den samme kode til flere kampe.

Den vigtigste forskel er, at en kontakt kan udføre matching mod flere forskellige værdityper:

def x = 1.23 def result = "" switch (x) {case "foo": result = "found foo" break case "bar": result + = "bar" break case [4, 5, 6, 'inList'] : result = "list" break case 12..30: result = "range" break case Number: result = "number" break case ~ / fo * /: result = "foo regex" break case {it <0}: / / eller {x <0} resultat = "negativ" pause standard: resultat = "standard"} println (resultat)

Eksemplet ovenfor udskrives nummer.

9.3. Sløjfer: mens

Groovy understøtter det sædvanlige mens sløjfer som Java gør:

def x = 0 def y = 5 mens (y--> 0) {x ++}

9.4. Sløjfer: til

Groovy omfavner denne enkelhed og opmuntrer kraftigt til sløjfer, der følger denne struktur:

for (variabel i iterabel) {body}

Det til løkke gentager sig iterabel. Ofte anvendte iterables er områder, samlinger, kort, arrays, iteratorer og optællinger. Faktisk kan ethvert objekt være en iterabel.

Seler omkring kroppen er valgfri, hvis den kun består af en sætning. Nedenfor er eksempler på iterering over en rækkevidde, liste, array, kortog strenge:

def x = 0 for (i i 0..9) {x + = i} x = 0 for (i i [0, 1, 2, 3, 4]) {x + = i} def array = (0. .4) .toArray () x = 0 for (i i array) {x + = i} def map = ['abc': 1, 'def': 2, 'xyz': 3] x = 0 for (e på kort) {x + = e.værdi} x = 0 for (v i kort.værdier ()) {x + = v} def tekst = "abc" def liste = [] for (c i tekst) {liste. tilføj (c)}

Objekt-iteration gør Groovy til-loop en sofistikeret kontrolstruktur. Det er en gyldig modstykke til at bruge metoder, der gentager sig over et objekt med lukninger, såsom brug Samling er hver metode.

Den største forskel er, at kroppen af ​​en til loop er ikke en lukning, det betyder, at denne krop er en blok:

for (x i 0..9) {println x}

der henviser til, at denne krop er en lukning:

(0..9). Hver {println it}

Selvom de ligner hinanden, er de meget forskellige i konstruktionen.

En lukning er et objekt alene og har forskellige funktioner. Det kan konstrueres et andet sted og overføres til hver metode. Dog kroppen af til-loop genereres direkte som bytecode ved sit udseende. Ingen specielle afgrænsningsregler gælder.

10. Håndtering af undtagelser

Den store forskel er, at kontrollerede undtagelser ikke håndteres.

For at håndtere generelle undtagelser kan vi placere den potentielt undtagelsesfremkaldende kode i en prøv / fange blok:

prøv {someActionThatWillThrowAnException ()} fang (e) // log fejlmeddelelsen, og / eller håndter på en eller anden måde}

Ved ikke at erklære den type undtagelse, vi fanger, fanges enhver undtagelse her.

11. Lukninger

Kort sagt, en lukning er en anonym blok af eksekverbar kode, som kan overføres til variabler og har adgang til data i den sammenhæng, hvor den blev defineret.

De ligner også anonyme indre klasser, selvom de ikke implementerer en grænseflade eller udvider en basisklasse. De ligner lambdas i Java.

Interessant nok kan Groovy drage fuld fordel af de JDK-tilføjelser, der er blevet introduceret for at understøtte lambdas, især streaming-API'en. Vi kan altid bruge lukninger, hvor lambda-udtryk forventes.

Lad os overveje eksemplet nedenfor:

def helloWorld = {println "Hello World"}

Variablen Hej Verden har nu en henvisning til lukningen, og vi kan udføre den ved at kalde dens opkald metode:

helloWorld.call ()

Groovy lader os bruge en mere naturlig metode til at ringe til syntaks - det påberåber sig opkald metode for os:

Hej Verden()

11.1. Parametre

Ligesom metoder kan lukninger have parametre. Der er tre varianter.

I sidstnævnte eksempel er der kun én parameter med standardnavnet, fordi der ikke er noget declpersistence_startared det. Den modificerede lukning, der udskriver, hvad den sendes, ville være:

def printTheParam = {println it}

Vi kunne kalde det sådan:

printTheParam ('hej') printTheParam 'hej'

Vi kan også forvente parametre i lukninger og videresende dem, når vi ringer:

def power = {int x, int y -> return Math.pow (x, y)} println power (2, 3)

Typedefinitionen af ​​parametre er den samme som variabler. Hvis vi definerer en type, kan vi kun bruge denne type, men kan også den og videregive alt, hvad vi vil:

def say = {hvad -> println hvad} siger "Hello World"

11.2. Valgfri retur

Den sidste erklæring om en lukning kan implicit returneres uden behov for at skrive en returerklæring. Dette kan bruges til at reducere kedelpladekoden til et minimum. Således kan en lukning, der beregner kvadratet af et tal, afkortes som følger:

def firkant = {it * it} println firkant (4)

Denne lukning gør brug af den implicitte parameter det og den valgfri returopgørelse.

12. Konklusion

Denne artikel gav en hurtig introduktion til Groovy-sproget og dets nøglefunktioner. Vi startede med at introducere enkle begreber såsom grundlæggende syntaks, betingede udsagn og operatorer. Vi demonstrerede også nogle mere avancerede funktioner såsom operatører og lukninger.

Hvis du vil finde flere oplysninger om sproget og dets semantik, kan du gå direkte til det officielle websted.


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