Rust does not support native string interpolation like Python or JavaScript; instead, you use the format! macro or the println! macro with {} placeholders to inject variables into strings. For compile-time string construction, prefer format!, while println! is ideal for immediate output to standard streams.
Here is how you construct a string using format!:
fn main() {
let name = "Alice";
let age = 30;
// Constructing a string in memory
let message = format!("Hello, {}! You are {} years old.", name, age);
println!("{}", message);
// Output: Hello, Alice! You are 30 years old.
}
You can also use named arguments for better readability when the order of variables might be confusing or when reusing variables:
fn main() {
let user = "Bob";
let score = 95;
// Using named arguments
let report = format!("User {user} scored {score} points.");
println!("{}", report);
// Output: User Bob scored 95 points.
}
The format! macro returns a String owned on the heap, which is useful when you need to store the result or pass it to a function. If you only need to display the result immediately, println! is slightly more efficient as it avoids allocating a new String on the heap. Both macros support the same formatting syntax, including type-specific formatting like {} for Debug ({:?}) or Display ({}), and numeric formatting like {:.2} for floating-point precision.
Be aware that format! performs a heap allocation. If you are in a performance-critical loop and need to avoid allocations, consider using write! with a String buffer that you reuse, or use Cow<'_, str> if you can sometimes avoid allocation entirely. However, for 99% of application logic, format! is the standard, safe, and idiomatic way to handle string composition in Rust.