Common Standard Macros

println!

The println! macro writes formatted text followed by a newline (\n) to the process's standard output stream (stdout).

Syntactic Forms

Invocation Form Example Behavior
Empty (newline only) println!(); Writes a single \n byte to stdout
Inline variable capture println!("user = {name}, id = {id:?}"); Captures local bindings name (Display) and id (Debug) directly
Positional arguments println!("{} + {} = {}", a, b, a + b); Substitutes arguments in order ({0}, {1}, {2})
Named arguments println!("{host}:{port}", host = "0.0.0.0", port = 80); Binds named placeholders explicitly in the call
fn main() {
    let service = "auth-api";
    let port = 8080_u16;
    let healthy = true;

    println!("Starting {service} on port {port} (healthy={healthy})");
    println!(); // Prints a blank line
    println!("Hex port: {port:#06x}, Binary flags: {:04b}", 0b1010);
}
Starting auth-api on port 8080 (healthy=true)

Hex port: 0x1f90, Binary flags: 1010

Under the Hood: format_args! and Zero Intermediate String Allocation

Unlike calling println!("{}", format!(...)), invoking println!("x = {x}") does not allocate a heap String. Instead, println! expands to std::io::_print(format_args!("x = {x}\n")), which constructs a stack-allocated fmt::Arguments<'_> value and streams the formatted chunks directly into io::stdout()'s line-buffered writer.

Locking stdout for High-Throughput Loops (StdoutLock)

Each call to println! acquires and releases a mutex lock on the global io::stdout() handle and flushes on every newline (when attached to a terminal). When printing thousands of lines in a tight loop, lock stdout() once and wrap it in a BufWriter with writeln!:

use std::io::{self, BufWriter, Write};

fn main() -> io::Result<()> {
    let stdout = io::stdout();
    let mut handle = BufWriter::new(stdout.lock());

    for i in 1..=3 {
        writeln!(handle, "Batch line #{i}")?;
    }
    handle.flush()?;
    Ok(())
}
Batch line #1
Batch line #2
Batch line #3

Panicking Behavior on Broken Pipe

If writing to stdout returns an I/O error, println! panics (or terminates on SIGPIPE). In CLI tools that pipe output into head/grep commands where broken pipes should be handled gracefully as io::Result<()>, use writeln!(io::stdout(), ...) instead of println!.