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

122
在Swift中,!表示解包一个可选项(可能的值)。
2个回答

135

println! 不是一个函数,它是一个。宏使用来区分它们与普通的方法调用。文档包含更多信息。

另请参见:


Rust使用Option类型表示可选数据。它有一个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)
}

问号运算符也适用于 Option,因此您可能会看到它用于解开值或从函数返回None。这与仅仅解包不同,因为程序不会出现恐慌:
fn foo() -> Option<i32> {
    None
}

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

29

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");

来源:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接