Jak piszesz ciągi wielowierszowe w Go?

612

Czy Go ma coś podobnego do wielowierszowych ciągów Pythona:

"""line 1
line 2
line 3"""

Jeśli nie, jaki jest preferowany sposób pisania ciągów znaków obejmujących wiele wierszy?

aeter
źródło

Odpowiedzi:

973

Zgodnie ze specyfikacją języka można użyć dosłownego ciągu literowego, w którym ciąg jest rozdzielany znakami odwrotnymi zamiast podwójnych cudzysłowów.

`line 1
line 2
line 3`
Mark Byers
źródło
176
Na marginesie: „surowy cytat”, jak się go nazywa, nie analizuje sekwencji specjalnych. Dlatego literałem ciągowym jest wybór, aby zapisywać wzorce wyrażeń regularnych, ponieważ zwykle zawierają one niestandardowe sekwencje specjalne, które spowodowałyby, że kompilator Go narzekałby na brak podwójnej zmiany znaczenia. Utrzymuje wzory w czystości i względnie czytelne.
jimt
10
Należy jednak zachować ostrożność podczas korzystania ze spacji końcowych. Na przykład, jeśli wstawisz po line 1nim spację , będzie ona niewidoczna w edytorze, ale obecna w ciągu.
Ory Band
2
@DanieleD To niewielki nonsekitur, ale który dialekt? Prawdopodobnie głównie MySQL? stackoverflow.com/a/10574031 Zauważ, że przez rozszerzenie tego samego argumentu, utrudnia to osadzanie znaczników lub skryptów powłoki (jeśli zdecydujesz się na użycie backsticka zamiast $(abcd)).
Ivan Vučica,
8
@KyleHeuton: Prawdopodobnie Daniele D używa znaku backstick w swoich zapytaniach SQL (jak często robią użytkownicy MySQL) i uważa, że ​​bolesne jest reprezentowanie go jako `` + '' + + i przerywanie kopiowania i pastowalności.
ruakh
1
Wadą tego jest to, że jeśli piszesz go w wciętym kodzie, tabulatory będą zawarte w ciągu, a pozbycie się ich sprawi, że Twój kod będzie wyglądał brzydko. W takich okolicznościach wolałbym skorzystać z odpowiedzi
Azeema
111

Możesz pisać:

"line 1" +
"line 2" +
"line 3"

który jest taki sam jak:

"line 1line 2line3"

W przeciwieństwie do używania tyknięć, zachowa znaki ucieczki. Pamiętaj, że znak „+” musi znajdować się w wierszu „wiodącym”, tzn .:

"line 1"
+"line 2"

generuje błąd.

mddkpp na gmail.com
źródło
32
To rozwiązanie nie jest analogiczne do wielowierszowych ciągów Pythona. Dzieli literał łańcucha na wiele linii, ale sam łańcuch nie zawiera wielu linii.
Ben Butler-Cole,
2
Ponieważ pozwala to zachować znaki specjalne, nowe wiersze można po prostu dodawać za pomocą \ni jest o wiele łatwiej pracować z ciągami dynamicznymi itp. Jeśli mam rację, zaakceptowana odpowiedź naprawdę dotyczy statycznych ciągów znaków w kodzie, aby wyglądały ładnie.
RisingSun
1
Czy nie byłoby to również bardzo nieefektywne? Niech łańcuch będzie 3x sekwencją 6 znaków: 6 + 2 * 6 + 3 * 6 = 36 znaków przydzielonych, gdy optymalne byłoby 18 (ponieważ ciągi są niezmienne, za każdym razem, gdy dodasz dwa ciągi, tworzony jest nowy ciąg o długości dwóch ciągi połączone).
N0thing
@ N0thing: jeśli istnieją tylko literały łańcuchowe, nie ma żadnych różnic w czasie wykonywania, ponieważ kompilator zoptymalizuje. Ale istnieje niewielka różnica (w mikrosekundach, a nawet nanosekundach) w czasie kompilacji.
dolmen
Uważam, że to najlepszy sposób na uzyskanie literału ciągu wielowierszowego z zakończeniami linii CRLF
ldanilek,
39

Z literałów łańcuchowych :

  • dosłowny ciąg znaków obsługuje multilinię (ale znaki specjalne nie są interpretowane)
  • interpretowany ciąg literału interpretuj znaki specjalne, takie jak „ \n”.

Ale jeśli ciąg składający się z wielu wierszy musi zawierać cudzysłów (`), wówczas będziesz musiał użyć interpretowanego literału ciągu:

`line one
  line two ` +
"`" + `line three
line four`

Nie można bezpośrednio wstawić cudzysłowu (`) w dosłownym łańcuchu literalnym (` `xx \).
Musisz użyć (jak wyjaśniono w „ jak wstawić cudzysłów w ciągu cudzysłowów? ”):

 + "`" + ...
VonC
źródło
33

Użyj ciągów literalnych nieprzetworzonych dla ciągów wieloliniowych:

func main(){
    multiline := `line 
by line
and line
after line`
}

Surowe literały łańcuchowe

Nieprzetworzone literały łańcuchowe to sekwencje znaków między tylnymi cudzysłowami, jak w `foo`. W cudzysłowie może występować dowolny znak z wyjątkiem cudzysłowu.

Znaczna część jest to, że jest surowy dosłowny nie tylko multi-line i być multi-line nie jest jedynym celem tego.

Wartość literału łańcucha surowego jest łańcuchem złożonym z niezinterpretowanych (domyślnie zakodowanych w UTF-8) znaków między cudzysłowami; w szczególności ukośniki odwrotne nie mają specjalnego znaczenia ...

Dlatego znaki ucieczki nie będą interpretowane, a nowe linie między tykami będą prawdziwymi nowymi liniami .

func main(){
    multiline := `line 
by line \n
and line \n
after line`

    // \n will be just printed. 
    // But new lines are there too.
    fmt.Print(multiline)
}

Powiązanie

Być może masz długą linię, którą chcesz przełamać i nie potrzebujesz w niej nowych linii. W takim przypadku możesz użyć konkatenacji ciągów.

func main(){
    multiline := "line " +
            "by line " +
            "and line " +
            "after line"

    fmt.Print(multiline) // No new lines here
}

Ponieważ interpretowane jest „”, interpretowane będą dosłowne znaki dosłowne.

func main(){
    multiline := "line " +
            "by line \n" +
            "and line \n" +
            "after line"

    fmt.Print(multiline) // New lines as interpreted \n
}
I159
źródło
12

Idź i ciągi wielowierszowe

Za pomocą tyknięć możesz mieć wieloliniowe łańcuchy:

package main

import "fmt"

func main() {

    message := `This is a 
Multi-line Text String
Because it uses the raw-string back ticks 
instead of quotes.
`

    fmt.Printf("%s", message)
}

Zamiast używać symboli podwójnego cudzysłowu („) lub pojedynczego cudzysłowu ('), zamiast tego użyj znaku cofania, aby zdefiniować początek i koniec łańcucha. Następnie możesz zawinąć go w linie.

Jeśli jednak wcinasz ciąg znaków, pamiętaj, że białe znaki będą się liczyć.

Proszę sprawdzić plac zabaw i eksperymentuj z nim.

ASHWIN RAJEEV
źródło
4

Możesz umieścić treść z `` wokół niej, na przykład

var hi = `I am here,
hello,
`
liam
źródło
3

Musisz bardzo uważać na formatowanie i odstępy między wierszami w go, wszystko się liczy, a oto działająca próbka, spróbuj https://play.golang.org/p/c0zeXKYlmF

package main

import "fmt"

func main() {
    testLine := `This is a test line 1
This is a test line 2`
    fmt.Println(testLine)
}
David
źródło
3

możesz używać surowych literałów. Przykład

s:=`stack
overflow`
Prabesh P.
źródło
0

Dla mnie tego właśnie używam, jeśli dodawanie \nnie stanowi problemu.

fmt.Sprintf("Hello World\nHow are you doing today\nHope all is well with your go\nAnd code")

W przeciwnym razie możesz użyć raw string

multiline := `Hello Brothers and sisters of the Code
              The grail needs us.
             `
Ofonime Francis
źródło