Llaves en Rust: cómo mostrar { y } en format! sin errores

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿por qué Rust no ama las llaves?

\n\n

Si alguna vez has escrito en Rust e intentado mostrar algo como { "name": "Rust" } a través de println!, seguramente viste esto:

\n\n
println!("{ "name": "Rust" }"); // ¡Error de compilación!
\n\n

El compilador informa con sorna: "invalid reference to argument 'name' — no argument named 'name' found". Y te quedas perplejo: ¿cómo se muestran las llaves en una cadena? En Python se hace con {{ }}, pero allí es más simple. En Rust hay su propia filosofía: las llaves no son solo símbolos, sino parte de un potente sistema de formato, tomado de Python, pero con matices.

\n\n

En este artículo analizaremos todas las formas de escapar llaves en Rust: desde el básico {{ }} hasta trucos con Debug y raw string literals. Aprenderás a mostrar JSON, generar código y trabajar con plantillas sin caer en las trampas del compilador.

\n\n

¿Por qué las llaves son especiales?

\n\n

En Rust, las macros format!, println!, write! y format_args! usan las llaves como marcadores de sustitución. Por ejemplo:

\n\n
let name = "Rust";\nprintln!("¡Hola, {}!", name); // ¡Hola, Rust!
\n\n

Aquí {} es un placeholder que se reemplaza por el valor de la variable. Pero, ¿qué pasa si necesitas el propio símbolo { o }? Rust usa un truco simple: duplicar las llaves.

\n\n

Método 1: Duplicación clásica de {{ y }}

\n\n

La forma más simple y obvia es escribir dos llaves seguidas. El primer par {{ se convierte en una {, y }} en una }.

\n\n

Ejemplo 1: Escapado simple

\n
fn main() {\n    let text = format!("Función main() {{ ... }}");\n    println!("{}", text);\n    // Salida: Función main() { ... }\n}
\n\n

Ejemplo 2: Escapado con sustitución

\n
fn main() {\n    let lang = "Rust";\n    let year = 2015;\n    let result = format!("{{ \\"lang\\": \\"{}\\", \\"year\\": {} }}", lang, year);\n    println!("{}", result);\n    // Salida: { "lang": "Rust", "year": 2015 }\n}
\n\n

Este método funciona en todas partes: en println!, write!, format!. Recuerda la regla: dos llaves = una llave.

\n\n

Método 2: Argumentos nombrados y escapado

\n\n

Si usas argumentos nombrados (por ejemplo, {name}), el escapado también funciona, pero hay que tener cuidado con la posición de las llaves.

\n\n

Ejemplo 3: Placeholders nombrados y llaves

\n
fn main() {\n    let user = "Alice";\n    // Queremos mostrar: ¡Hola, {Alice}!\n    println!("¡Hola, {{{}}}!", user);\n    // Salida: ¡Hola, {Alice}!\n}
\n\n

Analicemos la cadena "¡Hola, {{{}}}!":\n

    \n
  • {{ → muestra {
  • \n
  • {} → sustituye user
  • \n
  • }} → muestra }
  • \n
\n

\n\n

Importante: la cantidad de llaves siempre debe ser par para el escapado. Si tienes {{{ es un error, ya que tres llaves no forman un par correcto.

\n\n

Método 3: Uso del formato Debug ({:?})

\n\n

A veces quieres mostrar una estructura de datos para que aparezca automáticamente con llaves. Por ejemplo, al depurar o generar JSON.

\n\n

Ejemplo 4: Salida de estructura mediante Debug

\n
#[derive(Debug)]\nstruct Point {\n    x: i32,\n    y: i32,\n}\n\nfn main() {\n    let p = Point { x: 10, y: 20 };\n    println!("{:?}", p);\n    // Salida: Point { x: 10, y: 20 }\n}
\n\n

El trait Debug añade automáticamente llaves alrededor de los campos. Es útil si necesitas mostrar rápidamente el estado de un objeto. Pero si necesitas exactamente JSON u otro

Blogs

Book Recommendations