¿Cuál es la sintaxis de un literal de cadena multilínea?
Me cuesta entender 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 \n
escape de nueva línea directamente). Si desea simplemente dividir una cadena en varias líneas por razones de formato, puede escapar de la nueva línea y el espacio en blanco inicial con un \
; Por ejemplo:
let string = "one line \
written over \
several";
es lo 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 largo, que puede incluir o no comillas, barras invertidas, etc., utilice 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;
};
"#;
Salidas:
#version 330
in vec4 v_color;
out vec4 color;
void main() {
color = v_color;
};
Enlace al patio de juegos
Si tiene secuencias de comillas dobles y símbolos hash dentro de su cadena, puede indicar un número arbitrario de hashes como delimitador:
let crazy_raw_string = r###"
My fingers #"
can#"#t stop "#"" hitting
hash##"#
"###;
Qué salidas:
My fingers #"
can#"#t stop "#"" hitting
hash##"#
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 de varias líneas y le quita la sangría para que el carácter que no sea un espacio más a la izquierda esté en la primera columna.
let s = indoc! {"
line one
line two
"};
El resultado es "line one\nline two\n"
.
Los espacios en blanco se conservan en relación con el carácter que no es un espacio situado más a la izquierda en el documento, por lo que lo siguiente tiene una sangría de 3 espacios en la línea dos en relación con la línea uno:
let s = indoc! {"
line one
line two
"};
El resultado es "line one\n line two\n"
.
Si desea tener un control granular preciso sobre los espacios en cadenas multilínea con saltos de línea sin utilizar una caja externa, puede hacer lo siguiente. Ejemplo tomado de mi propio proyecto.
impl Display for OCPRecData {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "OCPRecData {{\n\
\x20 msg: {:?}\n\
\x20 device_name: {:?}\n\
\x20 parent_device_name: {:?}\n\
}}", self.msg, self.device_name, self.parent_device_name)
}
}
Resultados en
OCPRecData {
msg: Some("Hello World")
device_name: None
parent_device_name: None
}
\n\
al final de cada línea de código se crea un salto de línea en la posición adecuada y se descartan más espacios en esta línea de código.\x20
(hexadecimal; 32 en decimal) es un espacio ASCII y un indicador del primer espacio que se conservará en esta línea de la cadena\x20\x20\x20\x20
y\x20
tiene el mismo efecto