打印!借用还是拥有变量?
Posted
技术标签:
【中文标题】打印!借用还是拥有变量?【英文标题】:Does println! borrow or own the variable? 【发布时间】:2015-08-07 15:30:43 【问题描述】:我对借贷和所有权感到困惑。在锈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' 是正确的,并且与第一个代码的结果相同。
【问题讨论】:
【参考方案1】:宏 print!
、println!
、eprint!
、eprintln!
、write!
、writeln!
和 format!
是一种特殊情况,它们隐式引用任何要格式化的参数。
为了方便起见,这些宏不像普通函数和宏那样工作;他们默默地引用引用的事实是这种差异的一部分。
fn main()
let x = 5;
println!("", x);
在 nightly 编译器上通过 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
。
【讨论】:
我不明白您为什么将这些宏称为“特殊情况”。这种隐式引用传递可以为任何宏实现。 @MarkusUnterwaditzer:当然,但问题是它看起来很正常,但实际上并非如此。当然,其他宏也可以使自己成为特殊情况。事实上,一般情况下强烈建议不要这样做。 也许这可以在书中指出?也让我很困惑。以上是关于打印!借用还是拥有变量?的主要内容,如果未能解决你的问题,请参考以下文章