Use the format! macro for creating new strings in memory and the println! or print! macros for outputting to the console. Both rely on the same curly brace {} placeholder syntax, supporting positional arguments, named arguments, and specific formatting options like width, alignment, and type conversion.
Here is a practical example showing the difference between creating a string and printing one, along with common formatting flags:
fn main() {
let name = "Alice";
let age = 30;
// 1. Create a new String in memory using format!
let greeting = format!("Hello, {}! You are {} years old.", name, age);
println!("{}", greeting);
// Output: Hello, Alice! You are 30 years old.
// 2. Print directly to stdout using println!
println!("User: {name}, Age: {age}"); // Named arguments (Rust 2021+)
// 3. Advanced formatting: width, alignment, and padding
let number = 42;
println!("Right aligned (width 5): {:5}", number); // " 42"
println!("Left aligned (width 5): {:<5}", number); // "42 "
println!("Zero-padded (width 5): {:05}", number); // "00042"
println!("Hexadecimal: {:x}", number); // "2a"
println!("Binary: {:b}", number); // "101010"
println!("Float (2 decimals): {:.2}", 3.14159); // "3.14"
}
Key syntax rules to remember:
- Positional: Use
{}for arguments in order, or{0},{1}to reference specific indices. - Named: Use
{variable_name}if you pass named arguments (e.g.,println!("Hi {name}", name = "Bob")). - Modifiers: Place a colon
:after the placeholder to add formatting flags (e.g.,{:width},{:0width},{:type}). - Debug vs Display: Use
{:?}to print theDebugrepresentation (useful for structs/vectors) and{}for theDisplaytrait (default string representation).
If you need to format a string inside a loop or a function, format! is your go-to tool because it returns a String type, whereas println! returns (). Always prefer format! when you need to store, manipulate, or return the formatted text.