Introduksjon til Groovy Language

1. Oversikt

Groovy er et dynamisk skriptspråk for JVM. Den kompileres for å bytekode og blander seg sømløst med Java-kode og biblioteker.

I denne artikkelen skal vi se på noen av de viktigste egenskapene til Groovy, inkludert grunnleggende syntaks, kontrollstrukturer og samlinger.

Deretter vil vi se på noen av hovedfunksjonene som gjør det til et attraktivt språk, inkludert null sikkerhet, implisitt sannhet, operatører og strenger.

2. Miljø

Hvis vi vil bruke Groovy i Maven-prosjekter, må vi legge til følgende i pom.xml:

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

Den siste Maven-pluginen finner du her og den siste versjonen av groovy-all her.

3. Grunnleggende funksjoner

Det er mange nyttige funksjoner i Groovy. La oss nå se på de grunnleggende byggesteinene i språket og hvordan det skiller seg fra Java.

La oss nå se på de grunnleggende byggesteinene i språket og hvordan det skiller seg fra Java.

3.1. Dynamisk skriving

En av de viktigste funksjonene i Groovy er støtten til dynamisk skriving.

Typedefinisjoner er valgfrie, og faktiske typer bestemmes ved kjøretid. La oss ta en titt på disse to klassene:

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

Disse to klassene definerer det samme getName metode, men den er ikke eksplisitt definert i en kontrakt.

Tenk deg at vi har en liste over gjenstander som inneholder ender og katter som har getName metode. Med Groovy kan vi gjøre følgende:

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

Koden vil kompilere, og utgangen av koden ovenfor vil være:

Duck Cat

3.2. Implisitt sannhetskonvertering

Som i JavaScript, vurderer Groovy hvert objekt til en boolsk om nødvendig, f.eks. når du bruker den i en hvis uttalelse eller når du negerer verdien:

if ("hei") {...} if (15) {...} if (someObject) {...}

Det er noen enkle regler å huske på denne konverteringen:

  • Ikke-tom Samlinger, arrays, kart evaluere til ekte
  • Matcher med minst en kamp evaluerer til ekte
  • Iteratorer og Oppregninger med ytterligere elementer tvinges til ekte
  • Ikke-tom Strenger, GSstrenger og CharSequences, er tvunget til ekte
  • Tall som ikke er null blir evaluert til ekte
  • Ikke-null objektreferanser er tvunget til ekte

Hvis vi ønsker å tilpasse den implisitte sannhetskonvertering, kan vi definere vår asBoolean () metode.

3.3. Import

Noen pakker importeres som standard, og vi trenger ikke å importere dem eksplisitt:

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 tre) transforms lar oss koble oss til Groovy-kompileringsprosessen og tilpasse den etter våre behov. Dette gjøres ved kompileringstidspunktet, så det er ingen ytelsesstraff når du kjører applikasjonen. Vi kan lage våre AST-transformasjoner, men vi kan også bruke de innebygde.

Vi kan skape våre transformasjoner, eller vi kan dra nytte av de innebygde.

La oss ta en titt på noen kommentarer som er verdt å vite.

4.1. Kommentar TypeChecked

Denne kommentaren brukes til å tvinge kompilatoren til å gjøre streng typekontroll for merkede kodestykker. Typekontrollmekanismen er utvidbar, så vi kan til og med tilby enda strengere typekontroll enn tilgjengelig i Java når det er ønskelig.

La oss ta en titt på eksemplet nedenfor:

klasse Universe {@TypeChecked int svar () {"førtito"}}

Hvis vi prøver å kompilere denne koden, ser vi følgende feil:

[Kontroll av statisk type] - Kan ikke returnere verdien av typen java.lang.Streng på metode som returnerer type int

De @TypeChecked merknader kan brukes på klasser og metoder.

4.2. Kommentar CompileStatic

Denne merknaden lar kompilatoren utføre kompileringstidskontroller slik det gjøres med Java-kode. Etter det utfører kompilatoren en statisk kompilering, og omgår dermed Groovy metaobject-protokollen.

Når en klasse er merket, vil alle metoder, egenskaper, filer, indre klasser, etc. i den merkede klassen bli typekontrollert. Når en metode er kommentert, brukes statisk kompilering bare på de elementene (nedleggelser og anonyme indre klasser) som er omsluttet av denne metoden.

5. Eiendommer

I Groovy kan vi lage POGOer (Plain Old Groovy Objects) som fungerer på samme måte som POJOer i Java, selv om de er mer kompakte fordi getters og setter genereres automatisk for offentlige eiendommer under kompilering. Det er viktig å huske at de bare blir generert hvis de ikke allerede er definert.

Dette gir oss fleksibiliteten til å definere attributter som åpne felt, samtidig som vi beholder muligheten til å overstyre atferden når vi setter eller henter verdiene.

Tenk på dette objektet:

klasse Person {String name String lastName}

Siden standardområdet for klasser, felt og metoder er offentlig - dette er en offentlig klasse, og de to feltene er offentlige.

Kompilatoren vil konvertere disse til private felt og legge til getName (), setName (), getLastName () og setLasfName () metoder. Hvis vi definerer setter og getter for et bestemt felt, vil ikke kompilatoren opprette en offentlig metode.

5.1. Snarveisnotasjoner

Groovy tilbyr en snarveisnotasjon for å få og sette egenskaper. I stedet for Java-måten å ringe til getters og settere, kan vi bruke en feltlignende tilgangsnotasjon:

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

6. Operatører

La oss nå se på nye operatører lagt til på toppen av de som er kjent fra vanlig Java.

6.1. Null-Safe Dereference

Den mest populære er den null-safe dereference-operatøren “?” som lar oss unngå a NullPointerException når du ringer til en metode eller får tilgang til en eiendom til en null gjenstand. Det er spesielt nyttig i kjedede samtaler der a null verdi kan forekomme på et tidspunkt i kjeden.

For eksempel kan vi trygt ringe:

Strengnavn = person? .Organisering? .Foreldre? .Navn

I eksemplet ovenfor hvis en person, person. organisering, eller organisasjon. foreldre er null, deretter null blir returnert.

6.2. Elvis Operator

Elvis-operatøren “?:”Lar oss kondensere ternære uttrykk. Disse to er ekvivalente:

Strengnavn = person.navn?: Standardnavn

og

Strengnavn = person.navn? person.navn: standardnavn

De tildeler begge verdien av person.navn til navnevariabelen hvis den er Groovy sant (i dette tilfellet ikke null og har en ikke-null lengde).

6.3. Romskipoperatør

Romskipoperatøren “” er en relasjonsoperatør som utfører som Java sammenligne med() som sammenligner to objekter og returnerer -1, 0 eller +1, avhengig av verdiene til begge argumentene.

Hvis venstre argument er større enn høyre, returnerer operatøren 1. Hvis venstre argument er mindre enn høyre, returnerer operatøren −1. Hvis argumentene er like, returneres 0.

Den største fordelen med å bruke sammenligningsoperatørene er jevn håndtering av null slik at x y vil aldri kaste en NullPointerException:

println 5 null

Ovenstående eksempel vil skrive ut 1 som et resultat.

7. Strenger

Det er flere måter å uttrykke strenglitteratur på. Tilnærmingen som brukes i Java (dobbel siterte strenger) støttes, men det er også lov å bruke enkelt anførselstegn når det foretrekkes.

Flerstrengede strenger, noen ganger kalt heredocs på andre språk, støttes også ved hjelp av trippel anførselstegn (enten enkelt eller dobbelt).

Flerstrengede strenger, noen ganger kalt heredocs på andre språk, støttes også ved hjelp av trippel anførselstegn (enten enkelt eller dobbelt).

Strenger definert med doble anførselstegn støtter interpolering ved hjelp av ${} syntaks:

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

Faktisk kan ethvert uttrykk plasseres inne i ${}:

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

En streng med doble anførselstegn kalles en GString hvis den inneholder et uttrykk ${}, ellers er det en slette String gjenstand.

Koden nedenfor kjører uten å mislykkes i testen:

def a = "hei" hevder a.class.name == 'java.lang.String' def b = 'hallo' hevder b.class.name == 'java.lang.String' def c = "$ {b} "hevder c.class.name == 'org.codehaus.groovy.runtime.GStringImpl'

8. Samlinger og kart

La oss ta en titt på hvordan noen grunnleggende datastrukturer håndteres.

8.1. Lister

Her er litt kode for å legge til noen få elementer i en ny forekomst av ArrayList i Java:

Listeliste = ny ArrayList (); list.add ("Hei"); list.add ("Verden");

Og her er den samme operasjonen i Groovy:

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

Lister er som standard av typen java.util.ArrayList og kan også erklæres eksplisitt ved å ringe til den tilsvarende konstruktøren.

Det er ikke en egen syntaks for en Sett, men vi kan bruke type tvang for det. Enten bruk:

Angi hilsen = ['Hei', 'Verden']

eller:

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

8.2. Kart

Syntaksen for en Kart er lik, om enn litt mer ordentlig, fordi vi trenger å kunne spesifisere nøkler og verdier avgrenset med kolon:

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

Etter denne initialiseringen vil vi få en ny LinkedHashMap med oppføringene: Key1 -> Value1, Key2 -> Value 2, Key3 -> Another Value.

Vi kan få tilgang til oppføringer på kartet på mange måter:

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

9. Kontrollstrukturer

9.1. Betingelser: hvis-annet

Groovy støtter betinget hvis / annet syntaks som forventet:

hvis (...) {// ...} annet hvis (...) {// ...} annet {// ...} 

9.2. Betingelser: bryterveske

De bytte om uttalelse er bakoverkompatibel med Java-kode, slik at vi kan gå gjennom saker som deler den samme koden for flere kamper.

Den viktigste forskjellen er at en bytte om kan utføre samsvar mot flere forskjellige verdityper:

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" standard: resultat = "standard"} println (resultat)

Eksemplet ovenfor vil skrives ut Nummer.

9.3. Sløyfer: samtidig som

Groovy støtter det vanlige samtidig som sløyfer som Java gjør:

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

9.4. Sløyfer: til

Groovy omfavner denne enkelheten og oppfordrer sterkt til sløyfer som følger denne strukturen:

for (variabel i iterabel) {body}

De til sløyfe itererer over iterabel. Ofte brukte iterables er områder, samlinger, kart, matriser, iteratorer og oppregninger. Faktisk kan ethvert objekt være en iterabel.

Bukseseler rundt kroppen er valgfrie hvis den bare består av en påstand. Nedenfor er eksempler på iterering over en område, liste, array, kart, og strenger:

def x = 0 for (i in 0..9) {x + = i} x = 0 for (i in [0, 1, 2, 3, 4]) {x + = i} def array = (0. .4) .toArray () x = 0 for (i array) {x + = i} def map = ['abc': 1, 'def': 2, 'xyz': 3] x = 0 for (e i kart) {x + = e.verdi} x = 0 for (v i kart.verdier ()) {x + = v} def tekst = "abc" def liste = [] for (c i tekst) {liste. legg til (c)}

Objekt-iterasjon gjør Groovy til-loop en sofistikert kontrollstruktur. Det er en gyldig motstykke til å bruke metoder som itererer over et objekt med lukkinger, for eksempel bruk Samlingen er hver metode.

Hovedforskjellen er at kroppen til en til sløyfe er ikke en lukking, dette betyr at denne kroppen er en blokk:

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

mens dette legemet er en lukking:

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

Selv om de ser like ut, er de veldig forskjellige i konstruksjonen.

En lukking er et eget objekt og har forskjellige funksjoner. Den kan konstrueres på et annet sted og overføres til Hver metode. Imidlertid kroppen av til-loop genereres direkte som bytekode på sitt utseende. Ingen spesielle avgrensningsregler gjelder.

10. Unntakshåndtering

Den store forskjellen er at håndtering av avmerkede unntak ikke håndheves.

For å håndtere generelle unntak kan vi plassere den potensielt unntaksfremkallende koden i en prøve / fange blokkere:

prøv {someActionThatWillThrowAnException ()} catch (e) // logg feilmeldingen, og / eller håndter på en eller annen måte}

Ved ikke å oppgi hvilken type unntak vi fanger, blir unntak fanget her.

11. Stengninger

Enkelt sagt, en lukking er en anonym blokk med kjørbar kode som kan overføres til variabler og har tilgang til data i konteksten der den ble definert.

De ligner også anonyme indre klasser, selv om de ikke implementerer et grensesnitt eller utvider en basisklasse. De ligner på lambdas på Java.

Interessant, Groovy kan dra full nytte av JDK-tilleggene som er introdusert for å støtte lambdas, spesielt streaming-API. Vi kan alltid bruke lukkinger der det forventes lambdauttrykk.

La oss se på eksemplet nedenfor:

def helloWorld = {println "Hello World"}

Variabelen Hei Verden har nå en referanse til nedleggelsen, og vi kan utføre den ved å ringe dens anrop metode:

helloWorld.call ()

Groovy lar oss bruke en mer naturlig metode for å ringe syntaks - den påkaller anrop metode for oss:

Hei Verden()

11.1. Parametere

I likhet med metoder kan nedleggelser ha parametere. Det er tre varianter.

I det siste eksemplet, fordi det ikke er noe declpersistence_startared, er det bare en parameter med standardnavnet den. Den modifiserte nedleggelsen som skriver ut det den sendes, vil være:

def printTheParam = {println it}

Vi kan kalle det slik:

printTheParam ('hallo') printTheParam 'hei'

Vi kan også forvente parametere i nedleggelser og sende dem når vi ringer:

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

Typedefinisjonen av parametere er den samme som variabler. Hvis vi definerer en type, kan vi bare bruke denne typen, men kan også den og gi inn alt vi vil:

def say = {what -> println what} si "Hello World"

11.2. Valgfri retur

Den siste uttalelsen om en nedleggelse kan implisitt returneres uten at det er nødvendig å skrive en returerklæring. Dette kan brukes til å redusere kjeleplatekoden til et minimum. Dermed kan en lukking som beregner kvadratet til et tall forkortes som følger:

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

Denne lukkingen gjør bruk av den implisitte parameteren den og valgfri returoppgave.

12. Konklusjon

Denne artikkelen ga en rask introduksjon til Groovy-språket og dets viktigste funksjoner. Vi startet med å introdusere enkle begreper som grunnleggende syntaks, betingede utsagn og operatører. Vi demonstrerte også noen mer avanserte funksjoner som operatører og nedleggelser.

Hvis du vil finne mer informasjon om språket og dets semantikk, kan du gå direkte til det offisielle nettstedet.


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