宏 print!、println!、eprint!、eprintln!、write!、writeln! 和 format! 是一种特殊情况,它们隐式引用任何要格式化的参数。
为了方便起见,这些宏不像普通函数和宏那样工作;他们默默地引用引用的事实是这种差异的一部分。
fn main() {
let x = 5;
println!("{}", x);
}
在 nightly 编译器上通过 rustc -Z unstable-options --pretty expanded 运行它,我们可以看到 println! 扩展为:
#![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,
)],
},
));
};
}
进一步整理,是这样的:
use std::{fmt, io};
fn main() {
let x = 5;
io::_print(fmt::Arguments::new_v1(
&["", "\n"],
&[fmt::ArgumentV1::new(&x, fmt::Display::fmt)],
// ^^
));
}
注意&x。
如果你写println!("{}", &x),那么你是在处理两个级别的引用;这具有相同的结果,因为&T 有一个std::fmt::Display 的实现,其中T 实现了Display(显示为impl<'a, T> Display for &'a T where T: Display + ?Sized),它只是通过它。你也可以写&&&&&&&&&&&&&&&&&&&&&&&x。