How to format strings with println! and format!
Short answer: println! prints and format! returns a String, and both read the same format
string: each {} takes one value — by position ({} or {1}), straight from a variable in scope
({name}), or by a name you pass (name = value) — and the spec after the colon ({:?},
{:>8}, {:.2}) decides how that value prints.
From a fresh project — cargo new string-demo, then replace src/main.rs with each block below.
The project name doesn’t matter; nothing in the output depends on it.
Filling a {} by position
Section titled “Filling a {} by position”fn main() { let first = "Ada"; let last = "Lovelace"; println!("{} {}", first, last); println!("{1}, {0} and {1} again", first, last);}Ada LovelaceLovelace, Ada and Lovelace againBare {}s take the arguments in order. Number them and any argument can be reused or reordered —
{1}, {0} prints the second one first. The values are borrowed, not consumed, so first and
last are still there afterwards.
Filling a {} from scope
Section titled “Filling a {} from scope”fn main() { let name = "Ada"; let year = 1843; println!("{name} was born in {year}");}Ada was born in 1843Name a variable inside the braces and the macro reads it straight from scope — no argument list at
all. A {} naming something that doesn’t exist is an ordinary “cannot find value” error, because
the capture really is the variable, not a key looked up at runtime. Building a string from
parts uses this spelling already.
Filling a {} by name
Section titled “Filling a {} by name”fn main() { let greeting = format!("{last}, {first}", first = "Ada", last = "Lovelace"); println!("{greeting}");}Lovelace, AdaNamed arguments sit after the format string as name = value pairs, so the order in the braces is
free, and the name doesn’t have to match any variable — sum = a + b is fine, since the value is
any expression. format! is the same syntax with a different job: it returns the String instead
of printing it.
Values that aren’t finished text: {:?}
Section titled “Values that aren’t finished text: {:?}”{} asks for Display, the formatting for finished human-facing text, and not every type has it.
A Vec doesn’t:
fn main() { let numbers = vec![1, 2, 3]; println!("{}", numbers);}error[E0277]: `Vec<{integer}>` doesn't implement `std::fmt::Display` --> src/main.rs:3:20 |3 | println!("{}", numbers); | -- ^^^^^^^ `Vec<{integer}>` cannot be formatted with the default formatter | | | required by this formatting parameter | = help: the trait `std::fmt::Display` is not implemented for `Vec<{integer}>` = note: in format strings you may be able to use `{:?}` (or `{:#?}` for pretty-print) instead
For more information about this error, try `rustc --explain E0277`.{:?} asks for Debug instead, and {:#?} prints it pretty:
fn main() { let numbers = vec![1, 2, 3]; println!("{:?}", numbers); println!("{:#?}", numbers);}[1, 2, 3][ 1, 2, 3,]Width, fill and precision
Section titled “Width, fill and precision”Everything after the colon is a spec for how the value prints:
fn main() { let name = "Ada"; let year = 1843; println!("[{name:>8}]"); println!("[{name:<8}]"); println!("[{name:^8}]"); println!("{year:05}"); println!("{:.2}", 3.14159); println!("{:.3}", 1.99999); println!("{{ and }}");}[ Ada][Ada ][ Ada ]018433.142.000{ and }> right-aligns, < left-aligns, ^ centres — the odd space goes right — and the number is the
minimum width, padded with spaces or with a leading 0. .2 is precision: two digits after the
point for a float, rounded and zero-padded (1.99999 prints as 2.000), and a hard cut at two
characters for a string. Doubled braces print one literal brace.
print! without the trailing newline — and the flush that makes its output appear — plus
eprintln! for standard error, each have their own page later in this chapter.
Related
Section titled “Related”- How to build a string from parts —
+,push_strandformat!, and what each one consumes - How to append to a String without extra allocations —
one buffer,
push_strandwrite! - What is the difference between String and &str? — the
owned buffer
format!hands back - Working with text — the rest of the chapter