Formatting & Printing
Rust formats text with macros (println!, format!, write!) backed by the std::fmt traits Display and Debug. Format specifiers control width, precision, and alignment.
Busca en todas las páginas de la documentación
Rust formats text with macros (println!, format!, write!) backed by the std::fmt traits Display and Debug. Format specifiers control width, precision, and alignment.
#[derive(Debug)]
struct User { id: u64, name: String }
fn main() {
let u = User { id: 1, name: "Ada".into() };
println!("{}", u.name);
println!("{:?}", u);
println!("{:#?}", u);
eprintln!("log: id={}", u.id);
}When to reach for this: CLI output, logs, test failures, and implementing user-visible string forms of your types.
use std::fmt;
struct Point { x: i32, y: i32 }
impl fmt::Display for Point {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({}, {})", self.x, self.y)
}
}
fn main() {
let p = Point { x: 3, y: 4 };
println!("point={p}");
println!("{:>10}", p);
let s = format!("moved {p}");
assert_eq!(s, "moved (3, 4)");
}What this demonstrates:
Display impl for custom formatting{:>10} right-aligns in 10 columnsformat! allocates a Stringeprintln! writes to stderr| Macro | Output | Returns |
|---|---|---|
println! | stdout + newline | () |
print! | stdout | () |
eprintln! | stderr + newline | () |
format! | none | String |
write! / writeln! | any fmt::Write | Result |
println!("{:.2}", 3.14159); // 3.14
println!("{:08x}", 255); // 000000ff
println!("{name}", name = "Rust"); // named argsDebug vs DisplayDebug: developer-oriented, often derivedDisplay: user-facing, manual impl required for custom types#? pretty-prints Debug with indentationprintln!(my_struct) without Display - Compile error. Fix: Derive Debug and use {:?}, or impl Display.Debug may escape strings oddly. Fix: Implement Display for human text.format! in hot loops - Allocates every call. Fix: Use write! to a buffer or reuse String with clear().{{ and }} produce literal braces. Fix: Double braces in format strings.Display::fmt - Should return fmt::Error, not panic. Fix: Propagate fmt::Result.| Alternative | Use When | Don't Use When |
|---|---|---|
tracing / log crates | Structured production logging | Quick scripts |
serde_json::to_string | Machine-readable output | Human CLI tables |
std::io::Write directly | Binary protocols | Text formatting |
to_string() on primitives | Simple scalar conversion | Custom layout rules |
Yes. They serve different audiences. Many types derive Debug and manually impl Display.
Use print! instead of println!.
f.pad_integral, f.precision(), f.width() read specifiers inside fmt impls.
write! returns Result. println! panics on I/O error (rare for stdout).
{:?} works. For custom: match and format inner value.
Blanket impl exists: types with Display get to_string().
Not in std. Crates like owo-colors wrap Display output.
Prints file/line and expression value to stderr. Handy for quick debugging.
itertools::format or collect to Vec then join for separators.
Std has no i18n. Use external crates for locale rules.
String vs &str#[derive(Debug)]Display, DebugStack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Revisado por Chris St. John·Última actualización: 19 jul 2026