rust - 打印!借用或拥有变量?

标签 rust ownership

我对借用和所有权感到困惑。在 rust 中documentation about reference and borrowing

let mut x = 5;
{
    let y = &mut x;
    *y += 1;
}
println!("{}", x);

他们说

println! can borrow x.

我对此感到困惑。如果 println! 借用 x,为什么它传递 x 而不是 &x

我尝试在下面运行这段代码

fn main() {
    let mut x = 5;
    {
        let y = &mut x;
        *y += 1;
    }
    println!("{}", &x);
}

除了我将 &x 传递给 println! 之外,此代码与上面的代码相同。它向控制台打印“6”,这是正确的,并且与第一个代码的结果相同。

最佳答案

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

这些宏的行为与普通函数不同,宏为方便起见;他们默默地接受引用的事实是这种差异的一部分。

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

通过 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) ,然后您将处理两个级别的引用;这具有相同的结果,因为存在 std::fmt::Display 的实现对于 &T其中 T工具 Display (显示为 impl<'a, T> Display for &'a T where T: Display + ?Sized )刚刚通过它。你也可以写 &&&&&&&&&&&&&&&&&&&&&&&x .


2023 年初更新:

  • 自 2021 年年中以来,所需的调用一直是 rustc -Zunpretty=expanded而不是 rustc -Zunstable-options --pretty=expanded .

  • 自 2023 年 1 月 28 日左右开始 ( https://github.com/rust-lang/rust/pull/106745 ),format_args!是 AST 的一部分,因此 println!("{}", x) 的扩展是::std::io::_print(format_args!("{0}\n", x)); , 不暴露 Arguments::new_v1建筑和&x方面。出于各种原因这很好(阅读 #106745’s description ),但破坏了我在这里的清晰演示 x仅供引用。 (这就是为什么我在末尾将其添加为注释而不是更新答案的原因——因为它不再有效。)

关于rust - 打印!借用或拥有变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58667800/

相关文章:

rust - 如何在 Rust 中过滤特定子特征的 RCed 特征对象向量?

rust - 在匹配语句中重用匹配变量

arrays - Rust:递归传递数组

rust - Rust match 语句的赋值

rust - 在 Rust 中实现链表时如何复制原始指针?

pointers - Rust 如何知道哪些类型拥有资源?

testing - 如何处理将可变借用的结构传递给函数闭包?

rust - 一个实现什么时候想要在 Rust 中获得 self 的所有权?

rust - 如何在类型签名中包含 ':Send'?

rust - 如何使用 PY03 实现返回 Python 对象的 Rust 函数