我对借贷和所有权感到困惑。在Rust documentation about reference and borrowing
中let mut x = 5;
{
let y = &mut x;
*y += 1;
}
println!("{}", x);
他们说
println!
可以借用x
。
我很困惑。如果println!
借用x
,为什么它会通过x
而不是&x
?
我尝试在下面运行此代码
fn main() {
let mut x = 5;
{
let y = &mut x;
*y += 1;
}
println!("{}", &x);
}
此代码与上述代码相同,只是我将&x
传递给println!
。它将'6'打印到控制台,这是正确的,与第一个代码的结果相同。
答案 0 :(得分:41)
宏print!
,println!
,eprint!
,eprintln!
,write!
,writeln!
和format!
是特例,为了方便起见,不像正常的事情那样表现。他们默默地参考的事实是这种差异的一部分。
fn main() {
let x = 5;
println!("{}", x);
}
在夜间编译器上通过rustc -Z unstable-options --pretty expanded
运行它,我们可以看到println!
扩展为:
#![feature(prelude_import)]
#![no_std]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std as std;
fn main() {
let x = 5;
::io::_print(::std::fmt::Arguments::new_v1(
{
static __STATIC_FMTSTR: &'static [&'static str] = &["", "\n"];
__STATIC_FMTSTR
},
&match (&x,) {
(__arg0,) => {
[
::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Display::fmt),
]
}
},
));
}
整理了很多,就是这样:
use std::fmt;
use std::io;
fn main() {
let x = 5;
io::_print(fmt::Arguments::new_v1(
&["", "\n"];
&[fmt::ArgumentV1::new(&x, fmt::Display::fmt)],
));
}
请注意&x
。
如果你写println!("{}", &x)
,那么你正在处理两个级别的引用;这有相同的结果,因为&T
的{{3}}实现T
实现Display
(显示为impl<'a, T> Display for &'a T where T: Display + ?Sized
),只是通过了它。你也可以写&&&&&&&&&&&&&&&&&&&&&&&x
。