Why does the println! function use an exclamation mark in Rust?

Rust

Rust Problem Overview


In Swift, ! means to unwrap an optional (possible value).

Rust Solutions


Solution 1 - Rust

println! is not a function, it is a macro. Macros use ! to distinguish them from normal method calls. The documentation contains more information.

See also:


Rust uses the Option type to denote optional data. It has an unwrap method.

Rust 1.13 added the question mark operator ? as an analog of the try! macro (originally proposed via RFC 243).

An excellent explanation of the question mark operator is in The Rust Programming Language.

fn foo() -> Result<i32, Error> {
    Ok(4)
}

fn bar() -> Result<i32, Error> {
    let a = foo()?;
    Ok(a + 4)
}

The question mark operator also extends to Option, so you may see it used to unwrap a value or return None from the function. This is different from just unwrapping as the program will not panic:

fn foo() -> Option<i32> {
    None
}

fn bar() -> Option<i32> {
    let a = foo()?;
    Some(a + 4)
}

Solution 2 - Rust

println! is a macro in rust, that means that rust will rewrite the code for you at compile time.

For example this:

fn main() {
    let x = 5;
    println!("{}", x);
}

Will be converted to something like this at compile time:

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std;
fn main() {
    let x = 5;
    {
        ::std::io::_print(::core::fmt::Arguments::new_v1(
            &["", "\n"],
            &match (&x,) {
                (arg0,) => [::core::fmt::ArgumentV1::new(
                    arg0,
                    ::core::fmt::Display::fmt,
                )],
            },
        ));
    };
}

*Notice that the &x is passed as a reference.

It's a macro because it does things that functions can't do:

  • It parses the format string at compile time, and generates type safe code
  • It has a variable number of arguments
  • It has named arguments ("keyword arguments")
    println!("My name is {first} {last}", first = "John", last = "Smith");
    

sources:

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCh&#233;yoView Question on Stackoverflow
Solution 1 - RustShepmasterView Answer on Stackoverflow
Solution 2 - RustTimo HuovinenView Answer on Stackoverflow