Cosa c'è di sbagliato in Groovy multi-line String?


105

Gli script Groovy sollevano un errore:

def a = "test"
  + "test"
  + "test"

Errore:

No signature of method: java.lang.String.positive() is 
applicable for argument types: () values: []

Anche se questo script funziona bene:

def a = new String(
  "test"
  + "test"
  + "test"
)

Perché?


5
Nel caso in cui aiuti qualcun altro, puoi ottenere lo stesso errore con un codice come def a = b + + "/" + c. In questo caso i due simboli + sono ovviamente il problema.
Geoff Hackworth

Risposte:


236

Dato che groovy non ha un marcatore EOL (come ;) si confonde se metti l'operatore sulla riga seguente

Questo invece funzionerebbe:

def a = "test" +
  "test" +
  "test"

poiché il parser Groovy sa di aspettarsi qualcosa nella riga seguente

Groovy vede il tuo originale defcome tre affermazioni separate. Il primo assegna testa a, i secondi due cercano di rendere "test"positivo (ed è qui che fallisce)

Con il new Stringmetodo del costruttore, il parser Groovy è ancora nel costruttore (poiché la parentesi non si è ancora chiusa), quindi può unire logicamente le tre linee insieme in una singola istruzione

Per le vere stringhe multilinea, puoi anche utilizzare le virgolette triple:

def a = """test
test
test"""

Creerà una stringa con test su tre righe

Inoltre, puoi renderlo più ordinato:

def a = """test
          |test
          |test""".stripMargin()

il stripMarginmetodo taglierà la parte sinistra (fino al carattere incluso |) da ogni riga


6
O semplicemente usa stripIndent () invece distripMargin() .
sschuberth

Sì, e ometti i |caratteri nelle righe extra
tim_yates

4
È possibile utilizzare virgolette doppie all'interno di """stringhe
tim_yates

3
Bene, ho modificato la risposta per mostrare come avresti bisogno di riformattare leggermente il codice per fare stripIndent() funzionare.
sschuberth

2
Perché a) l'avevo già postato come commento eb) non è molto diverso da questa risposta.
sschuberth

17

Puoi dire a Groovy che l'istruzione deve valutare oltre la fine della riga aggiungendo una coppia di parentesi ( ... )

def a = ("test"
  + "test"
  + "test")

Una seconda opzione consiste nell'usare una barra rovesciata,, \alla fine di ogni riga:

def a = "test" \
  + "test" \
  + "test"

FWIW, questo è identico a come funzionano le istruzioni multilinea di Python.


Il secondo è anche il modo in cui funzionano le istruzioni su più righe VBA: D (Solo con trattini bassi invece di barre rovesciate, perché VBA.)
Charles Wood

La seconda opzione non è riuscita per me in un file Jenkins. La prima opzione ha funzionato.
Silver,

Nitpick: la stringa multilinea Python non richiede l'operatore di concatenazione quando si usano parentesi, quindi non è esattamente la stessa cosa.
Big McLargeHuge

17

Simile a stripMargin(), potresti anche usare stripIndent () come

def a = """\
        test
        test
        test""".stripIndent()

Per colpa di

La riga con il minor numero di spazi iniziali determina il numero da rimuovere.

devi anche indentare il primo "test" e non metterlo subito dopo l'inital """(il che \assicura che la stringa multilinea non inizi con una nuova riga).


2
a cosa serve \?
Joe Phillips

4
Ho migliorato la mia ultima frase per spiegarla meglio.
sschuberth
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.