我对借贷和所有权感到困惑.铁 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);
}

这个代码与上面的代码相同,只是我通过了&xprintln!.它将"6"打印到控制台,这是正确的,结果与第一个代码相同.

推荐答案

print!println!eprint!eprintln!write!writeln!format!是一种特殊情况,隐式引用要格式化的任何参数.

这些宏的行为与正常函数不同,宏的行为是为了方便;事实上,他们默不作声地引用是这种差异的一部分.

fn main() {
    let x = 5;
    println!("{}", x);
}

在nightly compiler上运行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.

Rust相关问答推荐

为什么我需要在这个代码示例中使用&

如何从接收&;self的方法克隆RC

如何创建引用构造函数拥有的变量的对象?

如何在Rust中表示仅具有特定大小的数组

如何使用syn插入 comments ?

如何编写一个以一个闭包为参数的函数,该函数以另一个闭包为参数?

替换可变引用中的字符串会泄漏内存吗?

程序在频道RX上挂起

如何使用reqwest进行异步请求?

为什么 `Deref` 没有在 `Cell` 上实现?

tokio::sync::broadcast::Receiver 不是克隆

可以在旋转循环中调用try_recv()吗?

更新 rust ndarray 中矩阵的一行

使用 Rust 从 Raspberry Pi Pico 上的 SPI 读取值

错误:将自定义 proc_macro 与用Rust 的宝贝编写的属性一起使用时,无法在此范围内找到属性

如何判断服务器是否正确接收数据

为实现特征的所有类型实现显示

使用 `.` 将 T 转换为 &mut T?

使用泛型作为关联类型,没有幻像数据

类型组的通用枚举