🎓 A1Learner
🔍
0 of 142 lessons completed

Rust Format Specs

A format spec is the part after the colon in a slot that shapes a value. Each spec has pieces in a fixed order.

One slot, read left to right

A spec is read in a fixed order: fill and alignment, sign, #, 0, width, precision, type. This one asks for a field 8 wide, right-aligned:

println!("[{:>8}]", 42);

Centre it

Use ^ to centre the value. If the padding cannot split evenly, the extra space goes on the right:

println!("[{:^8}]", 42);
println!("[{:^7}]", 42);

Pick your own fill

Any character can fill the gaps. Put it just before the alignment arrow:

println!("[{:_^9}]", "hi");
println!("[{:-<8}]", "ok");

Zero as a fill character

Writing 0 as the fill pads with zeros — but the zeros land in front of everything, even the minus sign:

println!("[{:0>5}]", 42);
println!("[{:0>5}]", -42);

The 0 flag minds the sign

The 0 flag looks similar, but it is sign-aware: the zeros slide in after the sign, where they belong:

println!("[{:05}]", -42);
println!("[{:+08}]", 42);

The # flag adds a prefix

# asks for the alternate form. For numbers that means a base prefix — and the prefix counts towards the width:

println!("[{:#x}] [{:#b}] [{:#o}]", 255, 5, 9);
println!("[{:#08x}]", 255);

Precision trims text too

On a float, precision means digits after the point. On text, it is a maximum length — extra letters are cut off, and then the width applies:

println!("[{:.3}]", "hello");
println!("[{:>6.3}]", "hello");

Example

fn main() {
    println!("{:-^24}", " RECEIPT ");
    println!("{:<12}{:>8.2}", "Apples", 1.20);
    println!("{:<12}{:>8.2}", "Bread", 2.50);
    println!("{:<12}{:>8.2}", "TOTAL", 3.70);
    println!("code = {:#08x}", 48879);
}

Key points

  • The spec order is fixed: fill+align, sign, #, 0, width, .precision, type — write the pieces in that order or the code will not compile
  • Width is a minimum, never a maximum: a longer value prints in full and pushes everything after it along
  • Default alignment differs: numbers lean right, text leans left — say the arrow when it matters
  • The 0 flag beats fill and alignment for numbers.
  • It pads with zeros.
  • It keeps the zeros after the sign and any # prefix.
  • Precision is ignored for whole numbers: {:.3} on an integer changes nothing
  • Use {:p} to print a reference's memory address while debugging.
  • The address changes from run to run.
  • So never promise its exact text.
  • The pieces combine freely in one slot.

In this example, each line combines pieces from the snippets above. The title is centred in a field of 24. Dashes are the fill. There are 7 dashes first. Then comes the word RECEIPT with its spaces. Then 8 dashes follow. The odd dash goes on the right. Each row pairs two things. A name sits left-aligned in 12 places. A price sits right-aligned in 8 places, at 2 decimals. So the prices line up in a column. They are 1.20, 2.50 and the total 3.70. The last line shows # and the 0 flag together. 48879 in hex is beef. The prefix 0x is added. Zeros pad it to width 8 after the prefix. The result is 0x00beef.

Note

These pieces are the same in every formatting macro.

They are the same for every type that supports them.

Learn the order once.

It works everywhere.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Rust Playground

Exercise

What does format!("{:05}", -42) return?