Rust output macros: print!, eprintln!, write!, and format!
Rust’s formatting macros use the same format-string language, but they send the result to different destinations. Use format! for a new String, print! or println! for stdout, eprint! or eprintln! for stderr, and write! or writeln! for an existing writer.
If you know the destination and whether you want a newline but do not remember the macro, use the Rust Output Macro Chooser.
| Macro | Destination | Newline | Return |
|---|---|---|---|
format! |
new String |
no | String |
print! / println! |
stdout | no / yes | () |
eprint! / eprintln! |
stderr | no / yes | () |
write! / writeln! |
fmt::Write or io::Write |
no / yes | fmt::Result or io::Result |
format_args! |
deferred formatting arguments | no | fmt::Arguments |
stdout and stderr
Section titled “stdout and stderr”Use stdout for a program’s primary output. Use stderr for errors and progress that should remain separate from piped data.
println!("result={}", 42);
eprintln!("warning: retrying");print! does not append a newline. Because stdout is frequently line-buffered, call flush() when text must be visible immediately.
use std::io::{self, Write};
print!("Continue? [y/N] ");
io::stdout().flush().unwrap();See flush stdout in Rust for the std::io::Write import, prompt pattern, and the common “no method named flush” error.
Lock repeated output
Section titled “Lock repeated output”The standard documentation notes that print! locks stdout on every call. For a hot loop, lock once and write through the handle.
use std::io::{self, Write};
let stdout = io::stdout();
let mut output = stdout.lock();
for value in 0..3 {
writeln!(output, "{value}").unwrap();
}Write without an intermediate String
Section titled “Write without an intermediate String”write! targets either std::fmt::Write for Unicode strings or std::io::Write for byte-oriented output.
use std::fmt::Write;
let mut output = String::new();
write!(&mut output, "{:#06x}", 42).unwrap();
assert_eq!(output, "0x002a");Choose the destination
Section titled “Choose the destination”print!vsprintln!for stdout and newline behavior- flush stdout when output must appear before the next newline
eprint!andeprintln!for stderrwrite!andwriteln!for an existing writer or bufferformat!when you need an ownedStringformat_args!when an API acceptsfmt::Arguments