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版本:
以上就是为什么Rust的println!不会发生所有权转移?的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/87079.html
微信扫一扫
支付宝扫一扫