Typer af strenge i Groovy

1. Oversigt

I denne vejledning ser vi nærmere på de forskellige typer strenge i Groovy, herunder enkeltciterede, dobbeltciterede, tredobbelte og slashy strenge.

Vi undersøger også Groovys strengestøtte til specialtegn, multi-line, regex, escaping og variabel interpolation.

2. Forbedring java.lang.Streng

Det er sandsynligvis godt at begynde med at sige, at da Groovy er baseret på Java, har det alle Java'er Snor funktioner som sammenkædning, String API og de iboende fordele ved den konstante streng-pool på grund af det.

Lad os først se, hvordan Groovy udvider nogle af disse grundlæggende.

2.1. String sammenkædning

Strengsammenkædning er kun en kombination af to strenge:

def first = 'first' def second = "second" def concatenation = first + second assertEquals ('firstsecond', concatenation)

Hvor Groovy bygger på dette er med sine adskillige andre strengetyper, som vi ser på et øjeblik. Bemærk, at vi kan sammenkæde hver type ombytteligt.

2.2. String Interpolation

Nu tilbyder Java nogle meget grundlæggende skabeloner igennem printf, men Groovy går dybere og tilbyder strenginterpolation, processen med at skabelonstrenge med variabler:

def name = "Kacper" def result = "Hej $ {name}!" assertEquals ("Hello Kacper!", result.toString ())

Mens Groovy understøtter sammenkædning for alle dens strengetyper, det giver kun interpolation for bestemte typer.

2.3. GString

Men skjult i dette eksempel er en lille rynke - hvorfor ringer vi toString ()?

Rent faktisk, resultat er ikke af typen Snor, selvom det ligner det.

Fordi Snor klasse er endelig, Groovys strengklasse, der understøtter interpolering, GString, underklasserer det ikke. Med andre ord, for Groovy at levere denne forbedring, den har sin egen strengklasse, GString, som ikke kan strække sig fra Snor.

Kort sagt, hvis vi gjorde:

assertEquals ("Hello Kacper!", resultat)

dette påberåber sig assertEquals (Objekt, Objekt), og vi får:

java.lang.AssertionError: forventet: java.lang.String men var: org.codehaus.groovy.runtime.GStringImpl Forventet: java.lang.String Faktisk: org.codehaus.groovy.runtime.GStringImpl

3. Enkeltciteret streng

Sandsynligvis er den enkleste streng i Groovy en med enkelte citater:

def eksempel = 'Hej verden'

Under hætten er disse bare almindelig Java Strenge, og de er nyttige når vi skal have tilbud inden i vores streng.

I stedet for:

def hardToRead = "Kacper elsker \" Ringenes herre \ ""

Vi kan let sammenkæde en streng med en anden:

def easyToRead = 'Kacper elsker "Ringenes Herre"'

Fordi vi kan udveksle tilbudstyper som denne, reducerer det behovet for at undslippe tilbud.

4. Tredobbelt streng med et enkelt tilbud

En tredobbelt streng med et enkelt citat er nyttigt i sammenhængen med at definere indhold med flere linjer.

Lad os for eksempel sige, at vi har nogle JSON at repræsentere som en streng:

{"name": "John", "age": 20, "birthDate": null}

Vi behøver ikke at ty til sammenkædning og eksplicit nye linjetegn for at repræsentere dette.

Lad os i stedet bruge en tredobbelt enkelt citeret streng:

def jsonContent = '' '{"name": "John", "age": 20, "birthDate": null}' ''

Groovy gemmer dette som en simpel Java Snorog tilføjer den nødvendige sammenkædning og nye linjer for os.

Der er dog en udfordring, der endnu ikke skal overvindes.

Typisk for kodelæsbarhed indrykker vi vores kode:

def triple = '' første linje anden linje '' '

Men tredobbelt strenge med et enkelt citat bevarer det hvide rum. Dette betyder, at ovenstående streng virkelig er:

(newline) firstline (newline) secondline (newline)

ikke:

1 2 første linje (ny linje)anden linje (ny linje)

som måske vi havde tænkt os.

Følg med for at se, hvordan vi slipper af med dem.

4.1. Newline-karakter

Lad os bekræfte det vores tidligere streng starter med en newline-karakter:

assertTrue (triple.startsWith ("\ n"))

Det er muligt at fjerne denne karakter. For at forhindre dette er vi nødt til at sætte et enkelt tilbageslag \ som en første og sidste karakter:

def triple = '' \ firstline secondline '' '

Nu har vi i det mindste:

1 2 første linje (ny linje)anden linje (ny linje)

Et problem nede, et mere at gå.

4.2. Fjern kodeindrykket

Lad os derefter tage os af indrykket. Vi vil beholde vores formatering, men fjerne unødvendige tegn i mellemrummet.

Groovy String API kommer til undsætning!

For at fjerne ledende mellemrum på hver linje i vores streng kan vi bruge en af ​​Groovy-standardmetoderne, String # stripIndent ():

def triple = '' '\ firstline secondline' ''. stripIndent () assertEquals ("firstline \ nsecondline", triple)

Bemærk, at ved at flytte flåterne op ad en linje, Vi har også fjernet en efterfølgende newline-karakter.

4.3. Relativ indrykning

Det skal vi huske stripIndent kaldes ikke stripWhitespace.

stripIndent bestemmer indrykningsmængden fra den forkortede, ikke-hvide mellemrumslinje i strengen.

Så lad os ændre indrykket ganske lidt for vores tredobbelt variabel:

klasse TripleSingleQuotedString {@Test ugyldigt 'tredobbelt enkelt citeret med flerlinjestreng med sidste linje med kun mellemrum' () {def triple = '' 'firstline secondline \' '' .stripIndent () // ... use triple}}

Trykning tredobbelt ville vise os:

første linje anden linje

Siden første linje er den mindst indrykkede ikke-hvide mellemrumslinje, bliver den nulindrykket med anden linje stadig indrykket i forhold til det.

Bemærk også, at denne gang fjerner vi det bageste hvide område med en skråstreg, som vi så tidligere.

4.4. Strip med stripMargin ()

For endnu mere kontrol kan vi fortælle Groovy lige hvor vi skal starte linjen ved at bruge et | og stripMargin:

def triple = '' \ | firstline | secondline '' '. stripMargin ()

Hvilket ville vise:

første linje anden linje

Røret angiver, hvor linjen i strengen virkelig starter.

Vi kan også passere en Karakter eller CharSequence som et argument til stripMargin med vores brugerdefinerede afgrænsningskarakter.

Fantastisk, vi slap af med alt unødvendigt mellemrum, og vores streng indeholder kun det, vi vil have!

4.5. Undslipper specialtegn

Med alle ulemperne ved den tredobbelte single-quote-streng er der en naturlig konsekvens af at skulle undslippe enkelte citater og tilbageslag, der er en del af vores streng.

For at repræsentere specialtegn er vi også nødt til at undslippe dem med en tilbageslag. De mest almindelige specialtegn er en ny linje (\ n) og tabulering (\ t).

For eksempel:

def specialCharacters = '' hej \ 'John \'. Dette er tilbageslag - \ \ nAndre linje starter her '' '

vil medføre:

hej 'John'. Dette er tilbageslag - \ Anden linje starter her

Der er nogle få, vi skal huske, nemlig:

  • \ t - tabulering
  • \ n - ny linje
  • \ b - backspace
  • \ r - vognretur
  • \\ - tilbageslag
  • \ f - formfeed
  • \' - enkelt tilbud

5. Dobbeltciteret streng

Mens dobbelt-citerede strenge også bare er Java Strenge, deres specielle magt er interpolation. Når en dobbeltciteret streng indeholder interpolationstegn, slukker Groovy Java Snor til en GString.

5.1.GString og doven evaluering

Vi kan interpolere en dobbeltciteret streng ved at omgive udtryk med ${} eller med $ til punkterede udtryk.

Dens evaluering er dovendog - det konverteres ikke til en Snor indtil den overføres til en metode, der kræver en Snor:

def string = "eksempel" def stringWithExpression = "eksempel $ {2}" assertTrue (string instanceof String) assertTrue (stringWithExpression instance of GString) assertTrue (stringWithExpression.toString () instance of String)

5.2. Pladsholder med henvisning til en variabel

Den første ting, vi sandsynligvis vil gøre med interpolation, er at sende den en variabel reference:

def name = "John" def helloName = "Hello $ name!" assertEquals ("Hej John!", helloName.toString ())

5.2. Pladsholder med et udtryk

Men vi kan også give det udtryk:

def result = "result is $ {2 * 2}" assertEquals ("result is 4", result.toString ())

Vi kan selv sætte udsagn til pladsholdere, men det betragtes som dårlig praksis.

5.3. Pladsholdere hos prikoperatøren

Vi kan endda gå objekthierarkier i vores strenge:

def person = [name: 'John'] def myNameIs = "Jeg er $ person.name, og du?" assertEquals ("Jeg er John, og du?", myNameIs.toString ())

Med getters kan Groovy normalt udlede ejendomsnavnet.

Men hvis vi kalder en metode direkte, bliver vi nødt til at bruge ${}på grund af parenteserne:

def name = 'John' def result = "Store bogstaver: $ {name.toUpperCase ()}". toString () assertEquals ("Store bogstaver: JOHN", resultat)

5.4. hashCode i GString og Snor

Interpolerede strenge er bestemt godbidder i sammenligning med almindelige java.util.Streng, men de adskiller sig på en vigtig måde.

Se, Java Strenge er uforanderlige og så kaldende hashCode på en given streng returnerer altid den samme værdi.

Men, GString hashcodes kan variere siden Snor repræsentation afhænger af de interpolerede værdier.

Og faktisk, selv for den samme resulterende streng, har de ikke de samme hash-koder:

def string = "2 + 2 er 4" def gstring = "2 + 2 er $ {4}" assertTrue (string.hashCode ()! = gstring.hashCode ())

Således skal vi aldrig bruge GString som en nøgle i en Kort!

6. Triple Triple-Quote String

Så vi har set tredobbelt strenge med et enkelt citat, og vi har set strenge med dobbelt citat.

Lad os kombinere kraften fra begge dele for at få det bedste ud af begge verdener - multi-line strenginterpolation:

def name = "John" def multiLine = "" "Jeg hedder $ name." Dette er citat fra 'Krig og fred' "" ""

Bemærk også det vi behøvede ikke at undslippe enkelt- eller dobbeltcitater!

7. Slashy String

Lad os nu sige, at vi laver noget med et regelmæssigt udtryk, og vi undgår således tilbageslag overalt:

def mønster = "\ d {1,3} \ s \ w + \ s \ w + \\ w +"

Det er helt klart et rod.

For at hjælpe med dette, Groovy understøtter regex indbygget via skræmmende strenge:

def mønster = / \ d {3} \ s \ w + \ s \ w + \ w + / assertTrue ("3 blinde mus \ mænd" .matches (mønster))

Slashy strenge kan være både interpoleret og multi-line:

def navn = 'John' def eksempel = / Kære ([A-Z] +), Kærlighed, $ navn /

Selvfølgelig er vi nødt til at undslippe skråstreger:

def mønster = /.*foobar.*\/hello.*/ 

Og vi kan ikke repræsentere en tom streng med Slashy Stringda kompilatoren forstår // som en kommentar:

// if ('' == //) {// println ("Jeg kan ikke kompilere") //}

8. Dollarslashy streng

Slashy strenge er fantastiske, selvom det er en bummer at skulle undslippe den fremadgående skråstreg. For at undgå yderligere undslip fra en fremad skråstreg kan vi bruge en dollar-skråstreg.

Lad os antage, at vi har et regex-mønster: [0-3]+/[0-3]+. Det er en god kandidat til dollar-slashy streng, fordi vi i en slashy streng bliver nødt til at skrive: [0-3]+//[0-3]+.

Dollarslashy strenge er multiline GStrings der åbnes med $ / og lukkes med / $. For at undslippe en dollar eller en skråstreg fremad kan vi gå foran dollartegnet ($), men det er ikke nødvendigt.

Vi behøver ikke at flygte $ ind GString pladsholder.

For eksempel:

def name = "John" def dollarSlashy = $ / Hej $ name !, Jeg kan vise dig et $ -tegn eller et undsluppet dollartegn: $$ Begge skråstreger fungerer: \ eller / men vi kan stadig undslippe det: $ / Vi har for at undslippe åbnings- og lukningsafgrænsere: - $$$ / - $ / $$ / $ 

ville output:

Hej John !, Jeg kan vise dig et $ -tegn eller et undsluppet dollartegn: $ Begge skråstreger virker: \ eller / men vi kan stadig undslippe det: / Vi er nødt til at undslippe åbnings- og lukningsafgrænser: - $ / - / $

9. Karakter

De, der er fortrolige med Java, har allerede spekuleret på, hvad Groovy gjorde med tegn, da det bruger enkelte citater til strenge.

Rent faktisk, Groovy har ikke en eksplicit karakter bogstavelig.

Der er tre måder at lave en Groovy streng en faktisk karakter:

  • eksplicit brug af 'char' nøgleord ved erklæring af en variabel
  • ved hjælp af 'som' operatør
  • ved at kaste til 'char'

Lad os se på dem alle:

char a = 'A' char b = 'B' som char char c = (char) 'C' assertTrue (a instanceof Character) assertTrue (b instanceof Character) assertTrue (c instance of Character)

Den første måde er meget praktisk, når vi vil beholde tegnet som en variabel. De to andre metoder er mere interessante, når vi ønsker at videregive et tegn som et argument til en funktion.

10. Resume

Det var åbenbart meget, så lad os hurtigt opsummere nogle nøglepunkter:

  • strenge oprettet med et enkelt citat (‘) understøtter ikke interpolering
  • slashy og tredoblet dobbelt-quote strenge kan være multi-line
  • flerstrengede strenge indeholder mellemrumstegn på grund af kodeindrykket
  • backslash (\) bruges til at undslippe specialtegn i enhver type, undtagen dollar-skråstreger, hvor vi skal bruge dollar ($) for at flygte

11. Konklusion

I denne artikel diskuterede vi mange måder at oprette en streng i Groovy og dens understøttelse af multi-linjer, interpolering og regex.

Alle disse uddrag er tilgængelige på Github.

Og for at få flere oplysninger om funktionerne i selve Groovy-sproget, få en god start med vores introduktion til Groovy.