¿Cuál es la sintaxis para un literal de cadena multilínea?
135
Me está costando descubrir cómo funciona la sintaxis de cadenas en Rust. Específicamente, estoy tratando de descubrir cómo hacer una cadena de varias líneas.
Todos los literales de cadena se pueden dividir en varias líneas; por ejemplo:
let string ="line one
line two";
es una cadena de dos líneas, igual que "line one\nline two"(por supuesto, también se puede usar el \nescape de nueva línea directamente). Si desea dividir una cadena en varias líneas por motivos de formato, puede escapar de la nueva línea y del espacio en blanco inicial con un \; por ejemplo:
let string = "one line \
written over \
several";
es el mismo que "one line written over several".
Si desea saltos de línea en la cadena, puede agregarlos antes de \:
let string = "multiple\n\
lines\n\
with\n\
indentation";
Es lo mismo que "multiple\nlines\nwith\nindentation";
En caso de que desee hacer algo un poco más, que puede incluir o no comillas, barras diagonales inversas, etc., use la notación literal de cadena sin formato :
let shader =r#"
#version 330
in vec4 v_color;
out vec4 color;
void main() {
color = v_color;
};
"#;
Si tiene secuencias de comillas dobles y símbolos hash dentro de su cadena, puede denotar un número arbitrario de hashes como delimitador:
let crazy_raw_string =r###"
My fingers #"
can#"#t stop "#"" hitting
hash##"#
"###;
Pero ... solo necesita escapar de las nuevas líneas si no desea nuevas líneas en el resultado, y las cadenas en bruto no ayudan con eso.
Poolie
Las cadenas sin formato solo evitan que tenga que agregar una '\' al final de cada línea si no le importan las nuevas líneas (como cuando está incrustando código que es agnóstico de nueva línea como sombreadores y núcleos) o, como aludió a, cuando las nuevas líneas son realmente necesarias. Simplemente hace que sea más fácil incrustar código que quizás desee editar y no tener que molestarse con el '\' al final de cada línea. Eso es todo.
c0g
1
Si desea (o no le importa) nuevas líneas en la cadena resultante, las cadenas simples entre comillas dobles funcionarán perfectamente, como se muestra en los otros ejemplos. Si desea evitar nuevas líneas, las cadenas en bruto no son buenas. Realmente solo ayudan si el texto incluye comillas, barras invertidas, etc., como puede suceder en la fuente incrustada.
poolie
2
Ahora veo a qué te refieres y tienes toda la razón.
c0g
1
Sería útil mostrar el resultado de imprimir estas cadenas. De la respuesta en sí no puedo decir qué sucederá con las nuevas líneas y cómo se maneja la sangría.
bluenote10
48
La respuesta de Huon es correcta, pero si la sangría le molesta, considere usar Indoc, que es una macro de procedimiento para cadenas de varias líneas con sangría. Significa "documento sangrado". Proporciona una macro llamada indoc!()que toma un literal de cadena multilínea y lo desangra para que el carácter que no está en el espacio de la izquierda esté en la primera columna.
let s =indoc!{"
line one
line two
"};
El resultado es "line one\nline two\n".
El espacio en blanco se conserva en relación con el carácter no espacial más a la izquierda en el documento, por lo que la siguiente línea tiene dos espacios sangrados en relación con la línea uno:
Indique explícitamente , usando prosa, qué parte del código es importante para este comportamiento.
Shepmaster el
En este momento, esto parece no agregar nada nuevo a la respuesta aceptada , que dice: uno puede usar el \nescape de nueva línea [...] puede escapar de la nueva línea y el espacio en blanco inicial con un{backslash} . (Parece que es muy difícil escribir una barra invertida en el código en un comentario).
Shepmaster
2
Este comentario sugiere una forma de combinar los dos puntos en la respuesta aceptada: cómo puede producir una cadena de varias líneas, escrita como líneas múltiples en el código, pero que al mismo tiempo se permite —por razones estilísticas o de legibilidad— obtener su propia sangría en el código, sin que esta sangría termine en la cadena final. No está muy claro en el texto, pero es un caso de uso común y, por lo tanto, una sugerencia valiosa en mi humilde opinión. (Vea la respuesta de dtolnay para la versión en caja de esto.)
Respuestas:
Todos los literales de cadena se pueden dividir en varias líneas; por ejemplo:
es una cadena de dos líneas, igual que
"line one\nline two"
(por supuesto, también se puede usar el\n
escape de nueva línea directamente). Si desea dividir una cadena en varias líneas por motivos de formato, puede escapar de la nueva línea y del espacio en blanco inicial con un\
; por ejemplo:es el mismo que
"one line written over several"
.Si desea saltos de línea en la cadena, puede agregarlos antes de
\
:Es lo mismo que
"multiple\nlines\nwith\nindentation";
fuente
concat!()
macro para completar las opciones dadas ( doc.rust-lang.org/std/macro.concat.html )En caso de que desee hacer algo un poco más, que puede incluir o no comillas, barras diagonales inversas, etc., use la notación literal de cadena sin formato :
Si tiene secuencias de comillas dobles y símbolos hash dentro de su cadena, puede denotar un número arbitrario de hashes como delimitador:
fuente
La respuesta de Huon es correcta, pero si la sangría le molesta, considere usar Indoc, que es una macro de procedimiento para cadenas de varias líneas con sangría. Significa "documento sangrado". Proporciona una macro llamada
indoc!()
que toma un literal de cadena multilínea y lo desangra para que el carácter que no está en el espacio de la izquierda esté en la primera columna.El resultado es
"line one\nline two\n"
.El espacio en blanco se conserva en relación con el carácter no espacial más a la izquierda en el documento, por lo que la siguiente línea tiene dos espacios sangrados en relación con la línea uno:
El resultado es
"line one\n line two\n"
.fuente
En caso de que desee sangrar texto multilínea en su código:
El resultado será el siguiente:
fuente
\n
escape de nueva línea [...] puede escapar de la nueva línea y el espacio en blanco inicial con un{backslash}
. (Parece que es muy difícil escribir una barra invertida en el código en un comentario).