println!借用或拥有变量?

问题描述 投票:38回答:1

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

rust ownership
1个回答
40
投票

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),那么你正在处理两个级别的引用;这有相同的结果,因为有std::fmt::Display&T的实现,其中T实现Display(显示为impl<'a, T> Display for &'a T where T: Display + ?Sized),它只是通过它。你也可以写&&&&&&&&&&&&&&&&&&&&&&&x

© www.soinside.com 2019 - 2024. All rights reserved.