Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

{:?} and the Debug Format

Goal of This Episode

Use {:?} to print tuples and other things that “can’t be printed with {}.”

Main Text

So far we’ve printed everything with {}:

fn main() {
    let x = 42;
    println!("{}", x); // ✅ 42
}

Numbers, bools, and other basic types work fine with {}. But try printing a tuple with {}:

fn main() {
    let t = (1, 2, 3);
    println!("{}", t); // ❌ Compile error!
}

The compiler spits out a pile of error messages. In short: “This type doesn’t implement Display — I don’t know how to print it in a ‘nice-looking way.’”

The Fix: Use {:?}

fn main() {
    let t = (1, 2, 3);
    println!("{:?}", t); // ✅ (1, 2, 3)
}

{:?} is the Debug format. It’s not a “pretty format” for end users — it’s a “debugging format” for developers.

Display {} vs Debug {:?}

For simple types like numbers and bools, {} and {:?} print much the same thing. So what’s the point of {:?}?

It can print things {} can’t — like tuples. Tuples only have a Debug format, not a Display format.

The Pretty Version: {:#?}

If the data is complex (say, tuples nested in tuples), you can use {:#?} to print a “prettified Debug format”:

fn main() {
    let data = ((1, 2), (3, 4), (5, 6));
    println!("{:#?}", data);
}

A Handy Trick: the dbg! Macro

Rust also has a very convenient debugging tool, dbg!:

fn main() {
    let x = 5;
    dbg!(x);
    dbg!(x + 1);
}

It prints the file name, the line and column, and the value — super convenient:

[src/main.rs:3:5] x = 5
[src/main.rs:4:5] x + 1 = 6

Recap

  • {} is the Display format, meant for end users, but not every type supports it.
  • {:?} is the Debug format, meant for developers; compound types like tuples support it.
  • {:#?} is the prettified Debug format — clearer for complex data.
  • dbg! is a great helper for quick debugging; it prints the file name plus the line and column.