Rust Output

Rust produces console output primarily through the println! and format! macros, which share a common placeholder syntax.

The println! Macro

println! writes a line of text to standard output, followed by a newline. It is a macro (marked by the trailing !), not a function, which allows it to accept a variable number of arguments and check the format string at compile time.

Basic printing

fn main() {
    println!("Rust makes systems programming safer.");
}

Placeholders and Formatting

Curly braces {} act as placeholders that are filled in order by the arguments following the format string. You can also reference arguments by name for clarity, or by position when you need to reuse a value more than once.

Named and positional arguments

fn main() {
    let name = "Ferris";
    let age = 8;
    println!("{name} is {age} years old");
    println!("{0} says hi, {0} says bye", name);
}

Placeholders also support formatting specifiers after a colon, for example controlling decimal precision, width, and padding, similar to printf-style formatting in C but checked by the compiler at build time.

Formatting numbers

fn main() {
    let pi = 3.14159265;
    println!("Pi rounded: {:.2}", pi);
    println!("Padded number: {:5}", 42);
}

print! and eprintln!

print! behaves like println! but does not add a trailing newline, which is useful when building output piece by piece. eprintln! writes to standard error instead of standard output, which is the correct place for warnings and error messages so they can be redirected separately from normal program output.

Building Strings with format!

format! uses the exact same placeholder syntax as println!, but instead of printing to the console, it returns a new owned String. This is the standard way to build formatted text that you want to store, pass to a function, or write to a file rather than print immediately.

Building a String with format!

fn main() {
    let user = "admin";
    let action = "login";
    let log_line = format!("[EVENT] user '{}' performed '{}'", user, action);
    println!("{}", log_line);
}
  • println! prints text plus a trailing newline to standard output
  • print! prints text with no trailing newline
  • eprintln! prints to standard error, for warnings and diagnostics
  • format! returns a String instead of printing anything
  • {:?} uses the Debug format, useful for printing structs and vectors during development
  • {:#?} uses 'pretty' Debug formatting with indentation across multiple lines
MacroDestinationReturns
println!stdout() (nothing)
print!stdout() (nothing)
eprintln!stderr() (nothing)
format!nowhere (in memory)String
Note: The {:?} debug specifier requires the type to implement the Debug trait, which the compiler can auto-generate with #[derive(Debug)] on your own structs.
Note: Prefer named placeholders like {name} over positional {} when a format string has more than two or three arguments — it reads far more clearly.

Exercise: Rust Output

Which macro prints text to the console followed by a newline?