println!借用或拥有变量?

时间:2015-05-26 05:48:50

标签: rust ownership

我对借贷和所有权感到困惑。在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'打印到控制台,这是正确的,与第一个代码的结果相同。

1 个答案:

答案 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