信息发布→ 登录 注册 退出

为什么Rust的println!不会发生所有权转移?

发布时间:2025-09-28

点击量:

macro

println!是学习Rust时最常用的代码之一。我们可以连续多次调用它,下面的代码能够顺利编译,这一点再正常不过了。

let x = String::from("Hello!");println!("{}", x);println!("{}", x);

然而,我们明明传的是x,而不是&x,为什么没有发生所有权转移呢?

查看标准库的源码,我们可以看到:

#[macro_export]#[stable(feature = "rust1", since = "1.0.0")]#[allow_internal_unstable(print_internals, format_args_nl)]macro_rules! println { () => ($crate::print!("\n")); ($($arg:tt)*) => ({ $crate::io::_print($crate::format_args_nl!($($arg)*)); })}​#[unstable( feature = "format_args_nl", issue = "none", reason = "`format_args_nl` is only for internal \ language use and is subject to change" )]#[allow_internal_unstable(fmt_internals)]#[rustc_builtin_macro]#[macro_export]macro_rules! format_args_nl { ($fmt:expr) => {{ /* compiler built-in */ }}; ($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};}

这看起来更加复杂了,即使能够理解Rust宏,最后看到“compiler built-in”这句话也足以让人感到困惑。我们需要换个思路。

Rust宏是一种“元编程”的工具,宏会在编译期展开。如果我们能看到展开后的Rust代码,理解起来会更加容易。

幸运的是,Rust提供了查看宏展开后的代码的工具,不过需要使用Rust Nightly版本。

首先,我们需要安装Nightly版本。安装完成后,默认使用的是Stable版本。

从Stable版本切换到Nightly版本非常简单。

一切准备就绪后,我们可以展开宏,输入以下命令:

#![feature(prelude_import)]#![no_std]#[prelude_import]use ::std::prelude::v1::*;#[macro_use]extern crate std;fn main() { let x = String::from("Hello!"); { ::std::io::_print(::core::fmt::Arguments::new_v1(&["", "\n"], &match (&x,) { (arg0,) => [::core::fmt::ArgumentV1::new(arg0,::core::fmt::Display::fmt)], })); };}

在终端中,这将打印出宏展开后的代码。如果将这些代码复制并覆盖到main.rs文件中,同样可以编译通过并运行。

至此,关于问题的答案已经很清楚了:println!实际生成的代码使用了&x,即不可变借用。

最后,别忘了切换回Stable版本:

标签:# 工具  # mac  # ai  # 标准库  # 为什么  # rust  # 的是  # 我们可以  # 让人  # 是一种  # 过了  # 会在  # 可以看到  # 很清楚  # 别忘了  # 换个  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!