What benefits are there with making println a macro?

In this code, there is a ! after the println:

fn main() {
    println!("Hello, world!");

In most languages I have seen, the print operation is a function. Why is it a macro in Rust?


  • By being a procedural macro, println!() gains the ability to:

    1. Automatically reference its arguments. For example this is valid:

      let x = "x".to_string();
      println!("{}", x);
      println!("{}", x); // Works even though you might expect `x` to have been moved on the previous line.
    2. Accept an arbitrary number of arguments.

    3. Validate, at compile time, that the format string placeholders and arguments match up. This is a common source of bugs with C's printf().

    None of those are possible with plain functions or methods.

    See also: