Skip to content

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

Use stdout for a program’s primary output. Use stderr for errors and progress that should remain separate from piped data.

EXAMPLE: CI-CHECKEDCOMPILED · examples/format-output/src/reference_examples.rs#output-streams
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.

EXAMPLE: CI-CHECKEDCOMPILED · examples/format-output/src/reference_examples.rs#output-flush
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.

The standard documentation notes that print! locks stdout on every call. For a hot loop, lock once and write through the handle.

EXAMPLE: CI-CHECKEDCOMPILED · examples/format-output/src/reference_examples.rs#output-lock
use std::io::{self, Write};

let stdout = io::stdout();
let mut output = stdout.lock();
for value in 0..3 {
    writeln!(output, "{value}").unwrap();
}

write! targets either std::fmt::Write for Unicode strings or std::io::Write for byte-oriented output.

EXAMPLE: CI-CHECKEDTEST ASSERTED · examples/format-output/src/reference_examples.rs#output-string
use std::fmt::Write;

let mut output = String::new();
write!(&mut output, "{:#06x}", 42).unwrap();
assert_eq!(output, "0x002a");