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

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

在Swift中,!表示解包一个可选的(可能的值)。

println! is not a function, it is a macro. Macros use ! to distinguish them from normal method calls. The documentation 包含更多信息。

另请参阅:


Rust 使用 Option type to denote optional data. It has an unwrap 方法。

Rust 1.13 添加了问号运算符 ? 作为 try! 宏的模拟(最初通过 RFC 243 提出)。

The Rust Programming Language 中对问号运算符有很好的解释。

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

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

问号运算符也是 extends to Option,因此您可能会看到它用于解包函数中的值或 return None。这与仅仅解包不同,因为程序不会崩溃:

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

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

println!是rust中的一个宏,就是说rust会在编译时为你重写代码。

例如这个:

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

在编译时会被转换成这样:

#![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,
                )],
            },
        ));
    };
}

*请注意,&x 作为引用传递。

它是一个宏,因为它可以做函数不能做的事情:

  • 编译时解析格式化字符串,生成类型安全代码
  • 它有可变数量的参数
  • 它有命名参数(“关键字参数”)
    println!("My name is {first} {last}", first = "John", last = "Smith");
    

来源: