Rust format arguments: positional, named, and captured variables
A Rust replacement field can select a value four ways: use the next implicit argument, select a positional argument by index, use an explicit named argument, or capture an identifier that is already in scope. Formatting after the colon follows the same rules regardless of how the value was selected.
let language = "Rust";
assert_eq!(
format!("{language}: {1} before {0}", "first", "second"),
"Rust: second before first"
);Print a variable with println!
Section titled “Print a variable with println!”Modern Rust formatting can capture an identifier directly from the surrounding scope. If score is already a local variable, println!("score: {score}") prints it without repeating the variable as a separate macro argument.
The same capture syntax works across the standard formatting macros. format!("{score}"), println!("{score}"), and write!(writer, "{score}") use the same format-string argument model; the macro determines the destination, while the replacement field selects the value.
Use {:?} or {value:?} instead when the type is intended for Debug inspection rather than normal Display output. See Debug vs Display for that distinction.
Implicit arguments
Section titled “Implicit arguments”The shortest form is {}. Rust consumes the next unused implicit argument. This is usually the clearest form when values appear once and in order.
Fix “argument never used”
Section titled “Fix “argument never used””Every formatting argument must be selected by a replacement field. Rust rejects extra arguments rather than silently ignoring them.
fn main() {
println!("{}", 1, 2);
}If you see argument never used, either add a field for the value or remove the extra argument. With explicit positions and names, check that each supplied argument is referenced intentionally.
Explicit positions
Section titled “Explicit positions”An integer inside the braces selects a positional argument directly. {1} {0} can reverse two arguments without changing the argument list.
Explicit positions are useful when one argument is reused or when the output order differs from the call-site order. In longer format strings, avoid mixing styles so heavily that the argument flow becomes difficult to audit.
Named arguments and captured variables
Section titled “Named arguments and captured variables”You can pass an explicit named argument, or capture a local variable directly by name. Capture is concise when the local variable already has a meaningful name; explicit naming is useful when the label in the format string should differ from the local identifier.
Selection ends at the colon
Section titled “Selection ends at the colon”In {value:>8.2}, value selects the argument. Everything after : controls its representation: alignment, width, precision, flags, and formatting trait.
Width and precision can also be supplied from formatting arguments. The main Rust format strings reference shows the basic dynamic-width form, while precision explains what the precision value means for different output types.