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

Format Strings in Depth

Goal of This Episode

Learn println!’s assorted formatting tricks: the variable-capture shorthand, positional parameters, width, precision control, alignment, and base display.

This episode supplements Chapter 2.

Concept

We’ve been printing with println!("{}", x) all along, but Rust’s format strings are far more powerful. This episode covers the most-used tricks without covering everything — for the full formatting syntax, see the official documentation.

The Variable-capture Shorthand

You can write a variable’s name straight into the {}:

fn main() {
    let name = "Andy";
    println!("{name}"); // Equivalent to println!("{}", name)
}

This can be more convenient than writing {} and matching variables afterward, especially with many variables. Note only variable names go inside — no expressions ("{x + 1}" won’t work).

Positional Parameters

{} matches the following arguments in order by default, but you can write a number in the braces to name which argument explicitly (counting from 0):

fn main() {
    println!("{0} {1}", "hel", "lo"); // hel lo
    println!("{1} {0}", "hel", "lo"); // lo hel
}

The same argument can be reused without passing it twice:

fn main() {
    println!("{0}, {0}!", "wait"); // wait, wait!
}

When is this useful? Most commonly when one value appears several times in the string, or when you want to reorder the output without reordering the arguments.

Decimal Precision

Control the digits after the decimal point with :.N:

fn main() {
    let pi = 3.14159265;
    println!("{pi:.2}"); // Prints 3.14
}

Width

Specify a minimum width with :N — shortfalls get padded with spaces:

fn main() {
    let x = 42;
    println!("{x:5}"); // "   42" (width 5, right-aligned, space-padded)
}

Alignment

Control right, left, and center alignment explicitly with :>N, :<N, :^N:

fn main() {
    let name = "Andy";
    println!("[{name:>10}]"); // Right-aligned, width 10
    println!("[{name:<10}]"); // Left-aligned
    println!("[{name:^10}]"); // Centered
}

The Fill Character

Padding defaults to spaces, but another character can be specified:

fn main() {
    let id = 42;
    println!("{id:0>5}"); // Prints 00042 (padded with 0s)
}

Base Display

:b, :x, :o display numbers in binary, hexadecimal, and octal respectively:

fn main() {
    let n = 255;
    println!("{n:b}"); // 11111111
    println!("{n:x}"); // ff
    println!("{n:o}"); // 377
}

These formats combine — e.g. {:0>8b} is “binary, zero-padded to 8 digits.”

Escaping Braces

To print a literal { or } in a format string, use {{ and }}:

fn main() {
    println!("These are braces: {{}}"); // Prints: These are braces: {}
}

Example Code

fn main() {
    let name = "Ming";
    let score = 87.5678;

    // The variable-capture shorthand
    println!("Student: {name}");
    println!("Score: {score}");

    // Positional parameters: reordering, reuse
    println!("{1}'s score is {0}", score, name);
    println!("{0}! {0}! {0}!", "Go");

    // Decimal precision
    println!("Rounded to two places: {score:.2}");

    // Width
    println!("[{name:10}]"); // Strings left-align by default
    let x = 42;
    println!("[{x:10}]");    // Numbers right-align by default

    // Alignment
    println!("[{name:>10}]"); // Right
    println!("[{name:<10}]"); // Left
    println!("[{name:^10}]"); // Centered

    // Zero padding
    let id = 42;
    println!("ID: {id:0>5}");

    // Base display
    let value = 255;
    println!("Decimal: {value}");
    println!("Binary: {value:b}");
    println!("Hexadecimal: {value:x}");
    println!("Octal: {value:o}");

    // Combo: zero-pad + right-align + width 2 + hexadecimal
    let byte = 10;
    println!("0x{byte:0>2x}"); // Prints 0x0a

    // Combo: zero-pad + right-align + width 8 + binary
    println!("{byte:0>8b}"); // Prints 00001010

    // Printing braces themselves takes {{ and }}
    println!("Here's a brace pair: {{}}"); // Prints: Here's a brace pair: {}
}

Recap

  • println!("{x}") puts the variable name right in the braces — variables only, no expressions.
  • {0}, {1} pick arguments by number (from 0); the same argument can be reused.
  • {:.2} controls digits after the decimal point.
  • {:5} sets a minimum width.
  • {:>10}, {:<10}, {:^10} align right, left, and center.
  • {:0>5} pads with 0 to width 5.
  • {:b}, {:x}, {:o} display in binary, hexadecimal, octal.
  • Format options combine, e.g. {:0>8b} = zero-pad + right + width 8 + binary.
  • Print literal { and } by escaping as {{ and }}.