为什么 println! 函数在 Rust 中使用叹号?

在 Swift 中,!表示展开可选(可能的值)。

30418 次浏览

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)
}

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: