¿Qué se esconde detrás del misterioso r#""# en Rust? Explicación completa con código
¿Alguna vez te has encontrado en código Rust una extraña notación como r#"..."# y has pensado: «¿Qué operador mágico es este? ¿Es una sintaxis secreta para elegidos?» — no estás solo. Miles de desarrolladores han hecho esta pregunta en Stack Overflow, y hoy vamos a desentrañar de una vez por todas qué es, para qué sirve y cómo usar los literales de cadena cruda (raw string literals) en Rust.
En este artículo no solo daremos una definición seca. Recorreremos el camino desde el problema hasta la solución, escribiremos código real, veremos cómo r#""# te salva de dolores de cabeza y descubriremos dónde más se aplica esta sintaxis. ¡Vamos allá!
El problema: cuando las cadenas normales rompen el código
Imagina que estás escribiendo un parser JSON o una expresión regular. Dentro de la cadena necesitas usar comillas y barras invertidas. En código Rust normal, esto parece una pesadilla:
let json_string = "{\\"name\\": \\"Rust\\", \\"year\\": 2015}";let regex = "\\\\d{2}-\\\\d{2}-\\\\d{4}"; // fecha en formato DD-MM-YYYY¿Ves esto? Cada vez que necesitas una comilla dentro de la cadena, pones una barra invertida delante (\\"). Y si necesitas la propia barra invertida, escribes \\\\. El código rápidamente se convierte en una «escalera» de barras difícil de leer y depurar.
Pero esto no es nada. ¿Y si necesitas insertar un carácter de tabulación en la cadena? Entonces escribes \\t. ¿Y si necesitas el texto literal \\t? Tienes que escaparlo: \\\\t. Los ojos empiezan a doler ya en la segunda línea.
La solución: cadenas crudas — r#""#
Rust ofrece una salida elegante: los literales de cadena cruda. Se denotan con el prefijo r y se encierran entre #:
// Cadena cruda: todo lo de dentro se considera texto literallet raw_json = r#"{"name": "Rust", "year": 2015}"#;let raw_regex = r#"\\d{2}-\\d{2}-\\d{4}"#;¿Notas la diferencia? ¡Sin escapes! Las comillas de dentro son solo comillas. Las barras invertidas son solo barras. El compilador de Rust interpreta el contenido entre r#" y "# como texto puro, sin intentar interpretar secuencias de escape.
Esto es especialmente útil cuando trabajas con:
- Expresiones regulares — llenas de barras y caracteres especiales.
- JSON, XML, HTML — cadenas con muchas comillas.
- Consultas SQL — especialmente con comillas anidadas.
- Rutas de archivos en Windows —
C:\\Users\\Nameen lugar deC:\\\\Users\\\\Name. - Cualquier dato donde la barra invertida deba permanecer tal cual.
¿Cómo funciona bajo el capó?
Cuando Rust encuentra r#"..."#, simplemente copia todo lo que está entre el r#" inicial y el "# final en la cadena sin ningún procesamiento. Ningún se convierte en salto de línea, ningún \\t se convierte en tabulación. Es un fragmento de texto literal.
Pero hay un matiz: ¿qué hacer si dentro de la propia cadena aparece la secuencia "#? Por ejemplo, quieres insertar el texto #"hello"#. Si escribes r#"#"hello"#"#, el compilador se confundirá — ¿dónde termina el literal?
Para esto, Rust ideó las almohadillas múltiples. Puedes usar r##"..."##, r###"..."### y así sucesivamente. El número de # en ambos lados debe coincidir:
// La cadena contiene "# — usamos almohadillas dobleslet tricky = r##"Cadena con "# dentro"##;println!("{}", tricky); // Imprime: Cadena con "# dentro
// ¿Y si dentro hay "##? Entonces almohadillas triples:let very_tricky = r###"Texto con "## den