¿Cómo se escriben cadenas multilínea en Go?


Respuestas:


974

De acuerdo con la especificación del lenguaje , puede usar un literal de cadena sin procesar, donde la cadena está delimitada por comillas en lugar de comillas dobles.

`line 1
line 2
line 3`

176
Como nota al margen: la 'cita cruda' como se la llama, no analiza las secuencias de escape. Por lo tanto, el literal de cadena de elección es escribir patrones de expresión regular, ya que generalmente contienen secuencias de escape no estándar que harían que el compilador Go se quejara de no tener doble escape. Mantiene los patrones limpios y relativamente legibles.
jimt

10
Sin embargo, debe tener cuidado con esto cuando use espacios finales. Por ejemplo, si coloca un espacio después line 1, será invisible en su editor pero estará presente en la cadena.
Ory Band

2
@DanieleD Eso es un poco inseguro, pero ¿qué dialecto? Presumiblemente principalmente MySQL? stackoverflow.com/a/10574031 Tenga en cuenta que, por extensión del mismo argumento, es una molestia incrustar markdown o scripts de shell (si opta por utilizar la tecla de retroceso en lugar de $(abcd)).
Ivan Vučica

8
@KyleHeuton: Presumiblemente, Daniele D está utilizando el carácter de retroceso en sus consultas SQL (como suelen hacer los usuarios de MySQL), y le resulta doloroso tener que representarlo como `+" `" + `y romper la copia y la pastabilidad.
ruakh

1
La desventaja de esto es que si lo escribe dentro del código sangrado, se incluirán pestañas en la cadena, y deshacerse de ellas haría que su código se vea feo. En tales circunstancias, preferiría usar la respuesta de Azeem
Lost Crotchet el

112

Puedes escribir:

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

que es lo mismo que:

"line 1line 2line3"

A diferencia del uso de ticks posteriores, conservará los caracteres de escape. Tenga en cuenta que el "+" debe estar en la línea 'principal', es decir:

"line 1"
+"line 2"

genera un error


32
Esta solución no es análoga a las cadenas multilínea de Python. Divide la cadena literal en varias líneas, pero la cadena en sí no contiene varias líneas.
Ben Butler-Cole

2
Como esto conserva los caracteres de escape, se pueden agregar nuevas líneas simplemente \ny es mucho más fácil trabajar con cadenas dinámicas y demás. Si estoy en lo correcto, la respuesta aceptada realmente es para cadenas estáticas en el código para que se vea bonita.
RisingSun

1
¿No sería eso también muy ineficiente? Deje que la cadena sea 3x una secuencia de 6 caracteres: 6 + 2 * 6 + 3 * 6 = 36 caracteres asignados cuando óptimo sería 18 (ya que las cadenas son inmutables, cada vez que agrega dos cadenas se crea una nueva cadena con la longitud de las dos cadenas concatenadas).
Nada

@ N0thing: si solo hay literales de cadena, no hay diferencias de tiempo de ejecución ya que el compilador optimizará. Pero hay una pequeña diferencia (microsegundos, o incluso nanosegundos) en el tiempo de compilación.
dolmen

Creo que esta es la mejor manera de obtener un literal de cadena multilínea con terminaciones de línea CRLF
ldanilek

39

De literales de cadena :

  • el literal de cadena sin formato admite multilínea (pero los caracteres escapados no se interpretan)
  • cadena literal interpretada interpretar caracteres escapados, como ' \n'.

Pero, si su cadena de varias líneas debe incluir una comilla invertida (`), entonces deberá usar un literal de cadena interpretado:

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

No puede poner directamente una comilla invertida (`) en un literal de cadena sin formato (` `xx \). Debe
usar (como se explica en " ¿cómo poner una comilla invertida en una cadena con comillas invertidas? "):

 + "`" + ...

33

Use literales de cadena sin procesar para cadenas de varias líneas:

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

Literales de cadena sin procesar

Los literales de cadena sin formato son secuencias de caracteres entre comillas inversas, como en `foo`. Dentro de las comillas, puede aparecer cualquier carácter excepto la comilla inversa.

Una parte importante es que es prima literal no sólo multi-línea y para ser de varias líneas no es el único objetivo de la misma.

El valor de un literal de cadena sin formato es la cadena compuesta por los caracteres no interpretados (implícitamente codificados en UTF-8) entre las comillas; en particular, las barras invertidas no tienen un significado especial ...

Por lo tanto, los escapes no se interpretarán y las nuevas líneas entre ticks serán líneas realmente nuevas .

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)
}

Concatenación

Posiblemente tiene una línea larga que desea romper y no necesita líneas nuevas. En este caso, podría usar la concatenación de cadenas.

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

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

Dado que "" se interpreta, se interpretarán los escapes literales de cadena.

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

    fmt.Print(multiline) // New lines as interpreted \n
}

12

Ve y cuerdas multilínea

Usando ticks posteriores puede tener cadenas multilínea:

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)
}

En lugar de utilizar la comilla doble (") o los símbolos de comilla simple ('), utilice las marcas de retroceso para definir el inicio y el final de la cadena. Luego puede envolverlo en líneas.

Sin embargo, si sangra la cadena, recuerda que el espacio en blanco contará.

Por favor revise el patio de recreo y haga experimentos con él.


4

Puedes poner contenido con `` alrededor, como

var hi = `I am here,
hello,
`

3

Debe tener mucho cuidado con el formateo y el espaciado entre líneas, todo cuenta y aquí hay una muestra de trabajo, pruébelo 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)
}


0

Para mí esto es lo que uso si agregar \nno es un problema.

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

De lo contrario, puede usar el raw string

multiline := `Hello Brothers and sisters of the Code
              The grail needs us.
             `
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.