String Formatting (format!, println!)
Rust's formatting macros — println! , format! , and eprintln! — substitute values into a template using {} placeholders that also control width, precision, alignment, and number base.
Learn String Formatting (format!, println!) in our free Rust course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a…
Part of the free Rust course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll learn Display vs Debug formatting, positional and named arguments, the width/precision/fill mini-language, printing in binary and hex, and how to escape braces.
What You'll Learn in This Lesson
1️⃣ The Core Macros & Display vs Debug
println! writes to standard output, eprintln! to standard error, and format! returns a String instead of printing. The placeholder {} uses Display (user-facing); {:?} uses Debug (developer-facing, works for tuples and collections).
The (this went to stderr) line came from eprintln! . In your terminal both streams interleave, but they're separate channels — redirecting output ( cargo run > out.txt ) keeps stderr on screen.
2️⃣ Positional, Named & Inline Arguments
Empty {} consume arguments in order, but you can also reference them by index ( {0} , {1} ) to reuse or reorder, give them names, or — most concise — capture a variable directly inside the braces.
3️⃣ Width, Precision, Alignment & Radix
After a colon comes the format spec: an optional fill char and alignment ( < left, > right, ^ center), a minimum width, then a precision after a dot. You can also choose a number base with :b , :o , :x , and add # for the prefix.
These specs make aligned tables trivial: pick a width per column and an alignment, and rows line up perfectly. Note the last line — doubling braces ( {{}} ) prints a literal {} with no substitution.
Your turn. Fill in the blanks marked ___ , then run it.
Mini-Challenge: A Tidy Receipt
Use widths, alignment, and precision to print a perfectly columned receipt. Run it with cargo run and check the output.
Common Errors (and the fix)
- ❌ "X doesn't implement std::fmt::Display" — You used {} on a type without Display. ✅ Use {:?} and add #[derive(Debug)] .
- ❌ "invalid reference to positional argument" — A {0} index has no matching argument. ✅ Make sure indices line up with the arguments you passed.
- ❌ "argument never used" — You passed more arguments than placeholders. ✅ Add a placeholder or remove the extra argument.
- ❌ A literal { breaks the format — It's read as a placeholder. ✅ Double it: write {{ and }} for literal braces.
Pro Tips
- 💡 Prefer inline capture ( {name} ) for short, readable format strings.
- 💡 Use {:#?} when debugging nested data — the indented multi-line form is far easier to read.
- 💡 Build tables with fixed widths per column and alignment flags; everything lines up with zero manual spacing.
📋 Quick Reference — Format Specs
Spec
Effect
{} / {:?}
Display / Debug
{:#?}
Pretty (multi-line) Debug
{:>8} {:^8}
Right / center in width 8
{:.2}
2 decimal places
{:b} {:x} {:#x}
Binary / hex / hex w/ prefix
{{ }}
Literal braces
Frequently Asked Questions
🎉 Lesson Complete!
- ✅ println! prints, format! returns a String, eprintln! writes to stderr
- ✅ {} = Display, {:?} = Debug, {:#?} = pretty Debug
- ✅ Arguments can be positional, named, or inline-captured
- ✅ Specs control width, precision, fill, alignment, and radix; {{}} escapes braces
- ✅ Next lesson: Pattern Matching — match , if let , and destructuring
Practice quiz
Which placeholder uses Display formatting?
- {:?}
- {:#?}
- {}
- {:b}
Answer: {}. {} uses the Display trait for user-facing output.
Which placeholder uses Debug formatting?
- {:?}
- {}
- {:x}
- {:.2}
Answer: {:?}. {:?} uses the Debug trait, which works for tuples and collections.
What does format! do compared to println!?
- Prints to stderr
- Panics
- Reads input
- Returns a String instead of printing
Answer: Returns a String instead of printing. format! builds and returns a String rather than printing.
Where does eprintln! send its output?
- Standard output
- Standard error (stderr)
- A file
- A String
Answer: Standard error (stderr). eprintln! writes to standard error for diagnostics.
What does {:.2} do to a float?
- Keeps 2 decimal places
- Pads to width 2
- Prints in base 2
- Rounds to an integer
Answer: Keeps 2 decimal places. Precision .2 keeps two digits after the decimal point.
What does {:>8} do?
- Left-aligns in width 8
- Centers in width 8
- Right-aligns in width 8
- Prints 8 copies
Answer: Right-aligns in width 8. > means right-align, padded to a minimum width of 8.
What does {:x} print for 255?
- 255
- ff
- 0xff
- 11111111
Answer: ff. {:x} prints lowercase hexadecimal, so 255 becomes ff.
What does {:#x} print for 255?
- ff
- 255
- #ff
- 0xff
Answer: 0xff. The # flag adds the 0x prefix, giving 0xff.
How do you print a literal curly brace?
- \{
- Double it: {{ and }}
- {brace}
- You cannot
Answer: Double it: {{ and }}. Escape literal braces by doubling them: {{ prints { and }} prints }.
What does {:#?} produce?
- Hex output
- Display output
- Pretty multi-line Debug
- Binary output
Answer: Pretty multi-line Debug. {:#?} is the pretty, indented multi-line Debug form.
Continue this course
- Previous: Tuples & Arrays
- Next: Pattern Matching