¿Cuál es la sintaxis de un literal de cadena multilínea?

Resuelto Dumbapples asked hace 9 años • 5 respuestas

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.

Dumbapples avatar Apr 07 '15 10:04 Dumbapples
Aceptado

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 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";

huon avatar Apr 07 '2015 03:04 huon

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##"#
c0g avatar Feb 29 '2016 15:02 c0g

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".

dtolnay avatar Mar 21 '2016 02:03 dtolnay

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\x20y \x20 tiene el mismo efecto
phip1611 avatar Aug 07 '2020 20:08 phip1611