Soorten snaren in Groovy

1. Overzicht

In deze tutorial zullen we de verschillende soorten strings in Groovy nader bekijken, inclusief enkele aanhalingstekens, dubbele aanhalingstekens, drievoudige aanhalingstekens en slashy strings.

We zullen ook de tekenreeksondersteuning van Groovy onderzoeken voor speciale tekens, meerregelige, regex, escaping en variabele interpolatie.

2. Verbeteren java.lang.String

Het is waarschijnlijk goed om te beginnen met te stellen dat, aangezien Groovy gebaseerd is op Java, het alle Java's heeft Draad mogelijkheden zoals aaneenschakeling, de String API en de inherente voordelen van de String constant pool daardoor.

Laten we eerst kijken hoe Groovy enkele van deze basisprincipes uitbreidt.

2.1. String-aaneenschakeling

String-aaneenschakeling is slechts een combinatie van twee strings:

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

Waar Groovy hierop voortbouwt, is met zijn verschillende andere snaartypes, die we zo dadelijk zullen bekijken. Merk op dat we elk type onderling uitwisselbaar kunnen aaneenschakelen.

2.2. String-interpolatie

Nu biedt Java een aantal zeer eenvoudige sjablonen via printf, maar Groovy gaat dieper en biedt string interpolatie, het proces van het sjablonen van tekenreeksen met variabelen:

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

Hoewel Groovy aaneenschakeling ondersteunt voor al zijn tekenreekstypen, het biedt alleen interpolatie voor bepaalde typen.

2.3. GString

Maar verborgen in dit voorbeeld is een kleine rimpel - waarom bellen we toString ()?

Werkelijk, resultaat is niet van type Draad, zelfs als het er zo uitziet.

Omdat de Draad klasse is laatste, De tekenreeksklasse van Groovy die interpolatie ondersteunt, GString, maakt er geen subklasse van. Met andere woorden, voor Groovy om deze verbetering te bieden, het heeft zijn eigen snaarklasse, GString, die zich niet kunnen uitstrekken van Draad.

Simpel gezegd, als we dat deden:

assertEquals ("Hallo Kacper!", resultaat)

dit roept op assertEquals (Object, Object), en we krijgen:

java.lang.AssertionError: verwacht: java.lang.String maar was: org.codehaus.groovy.runtime.GStringImpl Verwacht: java.lang.String Actueel: org.codehaus.groovy.runtime.GStringImpl

3. String met enkele aanhalingstekens

Waarschijnlijk is de eenvoudigste string in Groovy er een met enkele aanhalingstekens:

def example = 'Hallo wereld'

Onder de motorkap zijn dit gewoon oud Java Snaren, en ze komen goed van pas wanneer we aanhalingstekens in onze string moeten hebben.

In plaats van:

def hardToRead = "Kacper houdt van \" Lord of the Rings \ ""

We kunnen gemakkelijk de ene string met de andere aaneenschakelen:

def easyToRead = 'Kacper houdt van "Lord of the Rings"'

Omdat we op deze manier citaattypen kunnen uitwisselen, is het minder nodig om tussen aanhalingstekens te ontsnappen.

4. Drievoudige tekenreeks met enkele aanhalingstekens

Een drievoudige tekenreeks met enkele aanhalingstekens is handig in de context van het definiëren van inhoud met meerdere regels.

Laten we bijvoorbeeld zeggen dat we er een paar hebben JSON vertegenwoordigen als een string:

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

We hoeven geen toevlucht te nemen tot aaneenschakeling en expliciete newline-tekens om dit weer te geven.

Laten we in plaats daarvan een drievoudige tekenreeks met enkele aanhalingstekens gebruiken:

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

Groovy slaat dit op als een simpele Java Draaden voegt de benodigde aaneenschakeling en nieuwe regels voor ons toe.

Er is echter nog een uitdaging die moet worden overwonnen.

Typisch voor de leesbaarheid van de code, laten we onze code inspringen:

def triple = '' 'firstline secondline' ''

Maar drievoudige tekenreeksen met enkele aanhalingstekens behouden witruimte. Dit betekent dat de bovenstaande string echt is:

(nieuwe regel) eerste regel (nieuwe regel) tweede regel (nieuwe regel)

niet:

1 2 firstline (nieuwe regel)secondline (nieuwe regel)

zoals we misschien bedoeld hadden.

Blijf ons volgen om te zien hoe we er vanaf komen.

4.1. Newline-teken

Laten we dat bevestigen onze vorige tekenreeks begint met een teken voor een nieuwe regel:

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

Het is mogelijk om dat personage te verwijderen. Om dit te voorkomen, moeten we een enkele backslash plaatsen \ als een eerste en laatste teken:

def triple = '' '\ firstline secondline' ''

Nu hebben we in ieder geval:

1 2 firstline (nieuwe regel)secondline (nieuwe regel)

Een probleem naar beneden, nog een te gaan.

4.2. Verwijder de code-inspringing

Laten we vervolgens voor de inspringing zorgen. We willen onze opmaak behouden, maar onnodige witruimtetekens verwijderen.

De Groovy String API komt te hulp!

Om voorloopspaties op elke regel van onze string te verwijderen, kunnen we een van de Groovy-standaardmethoden gebruiken, Tekenreeks # stripIndent ():

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

Houd er rekening mee dat door het vinkje een regel op te schuiven, we hebben ook een volgend nieuw-regel-teken verwijderd.

4.3. Relatieve inspringing

Dat moeten we onthouden stripIndent wordt niet genoemd stripWhitespace.

stripIndent bepaalt de hoeveelheid inspringing van de ingekorte, niet-witruimte regel in de string.

Dus laten we de inspringing behoorlijk veranderen voor onze verdrievoudigen variabele:

class TripleSingleQuotedString {@Test void 'triple single geciteerd met multiline string met laatste regel met alleen spaties' () {def triple = '' '\ firstline secondline \' '' .stripIndent () // ... use triple}}

Afdrukken verdrievoudigen zou ons laten zien:

firstline secondline

Sinds Eerste lijn de regel met de minst ingesprongen niet-witruimte is, wordt deze met nul ingesprongen tweede lijn nog steeds ingesprongen ten opzichte ervan.

Merk ook op dat we deze keer de achterliggende witruimte verwijderen met een schuine streep, zoals we eerder zagen.

4.4. Strip met stripMargin ()

Voor nog meer controle kunnen we Groovy precies vertellen waar de regel moet beginnen door een | te gebruiken en stripMargin:

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

Welke zou weergeven:

firstline secondline

De pijp geeft aan waar die regel van de string echt begint.

We kunnen ook een Karakter of CharSequence als argument voor stripMargin met ons aangepaste scheidingsteken.

Geweldig, we hebben alle onnodige witruimte verwijderd en onze string bevat alleen wat we willen!

4.5. Ontsnappen aan speciale karakters

Met alle voordelen van de drievoudige tekenreeks met enkele aanhalingstekens, is er een natuurlijk gevolg van het feit dat u moet ontsnappen aan enkele aanhalingstekens en backslashes die deel uitmaken van onze tekenreeks.

Om speciale tekens weer te geven, moeten we ze ook met een backslash laten ontsnappen. De meest voorkomende speciale tekens zijn een nieuwe regel (\ n) en tabellering (\ t).

Bijvoorbeeld:

def specialCharacters = '' 'hallo \' John \ '. Dit is een backslash - \ \ nTweede regel begint hier '' '

zal resulteren in:

Hallo John'. Dit is een backslash - \ De tweede regel begint hier

Er zijn er een paar die we moeten onthouden, namelijk:

  • \ t - tabellering
  • \ n - nieuwe lijn
  • \ b - backspace
  • \ r - wagenterugloop
  • \\ - backslash
  • \ f - formulierfeed
  • \' - alleenstaande citaat

5. Tekenreeks met dubbele aanhalingstekens

Terwijl tekenreeksen met dubbele aanhalingstekens ook gewoon Java zijn Snaren, hun speciale kracht is interpolatie. Als een string met dubbele aanhalingstekens interpolatietekens bevat, schakelt Groovy de Java uit Draad voor een GString.

5.1.GString en Lazy Evaluation

We kunnen een string met dubbele aanhalingstekens interpoleren door uitdrukkingen te omringen met ${} of met $ voor uitdrukkingen met punten.

De evaluatie ervan is lui, maar - het wordt niet geconverteerd naar een Draad totdat het wordt doorgegeven aan een methode waarvoor een Draad:

def string = "voorbeeld" def stringWithExpression = "voorbeeld $ {2}" assertTrue (string instantie van String) assertTrue (stringWithExpression instantie van GString) assertTrue (stringWithExpression.toString () instantie van String)

5.2. Tijdelijke aanduiding met verwijzing naar een variabele

Het eerste dat we waarschijnlijk met interpolatie willen doen, is het een variabele referentie sturen:

def name = "John" def helloName = "Hallo $ naam!" assertEquals ("Hallo John!", halloName.toString ())

5.2. Tijdelijke aanduiding met een uitdrukking

Maar we kunnen het ook uitdrukkingen geven:

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

We kunnen zelfs uitspraken in tijdelijke aanduidingen plaatsen, maar het wordt als een slechte praktijk beschouwd.

5.3. Tijdelijke aanduidingen met de puntoperator

We kunnen zelfs objecthiërarchieën in onze strings doorlopen:

def person = [naam: 'John'] def myNameIs = "Ik ben $ person.name, en jij?" assertEquals ("Ik ben John, en jij?", myNameIs.toString ())

Met getters kan Groovy meestal de accommodatienaam afleiden.

Maar als we een methode rechtstreeks aanroepen, moeten we ${}vanwege de haakjes:

def name = 'John' def result = "Hoofdletters naam: $ {name.toUpperCase ()}". toString () assertEquals ("Hoofdletters naam: JOHN", resultaat)

5.4. hashCode in GString en Draad

Geïnterpoleerde snaren zijn zeker een uitkomst in vergelijking met gewone snaren java.util.String, maar ze verschillen op een belangrijke manier.

Zie, Java Snaren zijn onveranderlijk, en zo roepend hashCode op een gegeven string retourneert altijd dezelfde waarde.

Maar, GString hashcodes kunnen variëren sinds de Draad weergave hangt af van de geïnterpoleerde waarden.

En eigenlijk, zelfs voor dezelfde resulterende string, zullen ze niet dezelfde hashcodes hebben:

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

We mogen dus nooit gebruiken GString als sleutel in een Kaart!

6. Drievoudige tekenreeks met dubbele aanhalingstekens

We hebben dus drievoudige tekenreeksen met enkele aanhalingstekens gezien, en we hebben tekenreeksen met dubbele aanhalingstekens gezien.

Laten we de kracht van beide combineren om het beste van twee werelden te krijgen - interpolatie van meerdere regels tussen strings:

def name = "John" def multiLine = "" "I'm $ name." Dit is een citaat uit 'Oorlog en vrede' "" ""

Merk dat ook op we hoefden niet te ontsnappen aan enkele of dubbele aanhalingstekens!

7. Slashy String

Laten we nu zeggen dat we iets doen met een reguliere expressie, en we dus overal aan backslashes ontsnappen:

def patroon = "\ d {1,3} \ s \ w + \ s \ w + \\ w +"

Het is duidelijk een puinhoop.

Om hierbij te helpen, Groovy ondersteunt native regex via slashy strings:

def pattern = / \ d {3} \ s \ w + \ s \ w + \ w + / assertTrue ("3 Blind Mice \ Men" .matches (patroon))

Slashy snaren kan zowel geïnterpoleerd als meerlijnig zijn:

def name = 'John' def example = / Beste ([A-Z] +), Liefs, $ naam /

Natuurlijk moeten we voorwaartse schuine strepen vermijden:

def patroon = /.*foobar.*\/hello.*/ 

En we kunnen geen lege string voorstellen met Slashy Stringaangezien de compiler begrijpt // als een opmerking:

// if ('' == //) {// println ("Ik kan niet compileren") //}

8. Dollar-Slashy String

Slashy-snaren zijn geweldig, hoewel het een spelbreker is om aan de voorwaartse slag te moeten ontsnappen. Om extra ontsnapping van een schuine streep te voorkomen, kunnen we een dollar-schuine streep gebruiken.

Laten we aannemen dat we een regex-patroon hebben: [0-3]+/[0-3]+. Het is een goede kandidaat voor een dollar-slashy string omdat we in een slashy string zouden moeten schrijven: [0-3]+//[0-3]+.

Dollar-slashy snaren zijn multiline GStrings die openen met $ / en sluiten met / $. Om aan een dollar of schuine streep te ontsnappen, kunnen we ervoor zorgen dat er een dollarteken ($) staat, maar dat is niet nodig.

We hoeven $ in niet te ontsnappen GString tijdelijke aanduiding.

Bijvoorbeeld:

def name = "John" def dollarSlashy = $ / Hallo $ naam !, ik kan je een $ -teken of een ontsnapt dollarteken laten zien: $$ Beide schuine strepen werken: \ of /, maar we kunnen er nog steeds aan ontsnappen: $ / We hebben om te ontsnappen aan het openen en sluiten van scheidingstekens: - $$$ / - $ / $$ / $ 

zou uitvoeren:

Hallo John !, ik kan je een $ -teken of een ontsnapt dollarteken laten zien: $ Beide schuine strepen werken: \ of /, maar we kunnen er nog steeds aan ontsnappen: / We moeten ontsnappen aan het openen en sluiten van het scheidingsteken: - $ / - / $

9. Karakter

Degenen die bekend zijn met Java hebben zich al afgevraagd wat Groovy deed met karakters, aangezien het enkele aanhalingstekens gebruikt voor strings.

Werkelijk, Groovy heeft geen expliciet letterlijk karakter.

Er zijn drie manieren om een Groovy teken een echt teken:

  • expliciet gebruik van het trefwoord ‘char 'bij het declareren van een variabele
  • met de ‘as'-operator
  • door te casten naar ‘char '

Laten we ze allemaal eens bekijken:

char a = 'A' char b = 'B' as char char c = (char) 'C' assertTrue (a instanceof Character) assertTrue (b instanceof Character) assertTrue (c instanceof Character)

De eerste manier is erg handig als we het teken als een variabele willen behouden. De andere twee methoden zijn interessanter als we een teken als argument aan een functie willen doorgeven.

10. Samenvatting

Dat was duidelijk veel, dus laten we snel enkele belangrijke punten samenvatten:

  • strings gemaakt met een enkel aanhalingsteken (‘) ondersteunen geen interpolatie
  • schuine en drievoudige tekenreeksen met dubbele aanhalingstekens kunnen uit meerdere regels bestaan
  • strings met meerdere regels bevatten spaties vanwege code-inspringing
  • backslash (\) wordt gebruikt om te ontsnappen aan speciale tekens in elk type, behalve dollar-slashy string, waar we dollar ($) moeten gebruiken om te ontsnappen

11. Conclusie

In dit artikel hebben we veel manieren besproken om een ​​tekenreeks in Groovy te maken en de ondersteuning ervan voor meerdere regels, interpolatie en regex.

Al deze fragmenten zijn beschikbaar op Github.

En voor meer informatie over de kenmerken van de Groovy-taal zelf, begin dan goed met onze introductie tot Groovy.