Curly Braces in Rust: How to Output { and } in format! Without Errors

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why Doesn't Rust Like Curly Braces?

\n\n

If you've ever written in Rust and tried to output something like { "name": "Rust" } via println!, you've probably seen this:

\n\n
println!("{ "name": "Rust" }"); // Compilation error!
\n\n

The compiler gleefully reports: "invalid reference to argument 'name' — no argument named 'name' found". And you're left puzzled: how do you output curly braces in a string? In Python, this is done with {{ }}, but it's simpler there. Rust has its own philosophy: curly braces are not just characters, but part of a powerful formatting system borrowed from Python, but with nuances.

\n\n

In this article, we'll cover all the ways to escape curly braces in Rust: from the basic {{ }} to tricks with Debug and raw string literals. You'll learn how to output JSON, generate code, and work with templates without falling into compiler traps.

\n\n

Why Are Curly Braces Special?

\n\n

In Rust, the macros format!, println!, write!, and format_args! use curly braces as placeholder markers. For example:

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

Here, {} is a placeholder that gets replaced with the variable's value. But what if you need the { or } character itself? Rust uses a simple trick: doubling the braces.

\n\n

Method 1: Classic Doubling {{ and }}

\n\n

The simplest and most obvious way is to write two curly braces in a row. The first pair {{ turns into one {, and }} turns into one }.

\n\n

Example 1: Simple Escaping

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

Example 2: Escaping with Substitution

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

This method works everywhere: in println!, write!, format!. Remember the rule: two braces = one brace.

\n\n

Method 2: Named Arguments and Escaping

\n\n

If you use named arguments (e.g., {name}), escaping still works, but you need to be careful with the placement of braces.

\n\n

Example 3: Named Placeholders and Braces

\n
fn main() {\n    let user = "Alice";\n    // We want to output: Hello, {Alice}!\n    println!("Hello, {{{}}}!", user);\n    // Output: Hello, {Alice}!\n}
\n\n

Let's break down the string "Hello, {{{}}}!":\n

    \n
  • {{ → outputs {
  • \n
  • {} → substitutes user
  • \n
  • }} → outputs }
  • \n
\n

\n\n

Important: the number of braces is always even for escaping. If you have {{{ — that's an error, because three braces do not form a valid pair.

\n\n

Method 3: Using Debug Format ({:?})

\n\n

Sometimes you want to output a data structure so that it automatically displays with curly braces. For example, during debugging or JSON generation.

\n\n

Example 4: Outputting a Structure via 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    // Output: Point { x: 10, y: 20 }\n}
\n\n

The Debug trait automatically adds braces around the fields. This is convenient if you need to quickly display the state of an object. But if you need exactly JSON or another

Blogs

Book Recommendations