问题描述
我对借用和所有权感到困惑.在 Rust 关于引用和借用的文档
I am confused with borrowing and ownership. In the Rust documentation about reference and borrowing
let mut x = 5;
{
let y = &mut x;
*y += 1;
}
println!("{}", x);
他们说
println!
可以借用x
.
我对此感到困惑.如果println!
借用了x
,为什么它通过x
而不是&x
?
I am confused by this. If println!
borrows x
, why does it pass x
not &x
?
我尝试在下面运行此代码
I try to run this code below
fn main() {
let mut x = 5;
{
let y = &mut x;
*y += 1;
}
println!("{}", &x);
}
此代码与上面的代码相同,只是我将 &x
传递给 println!
.它向控制台打印6",这是正确的并且与第一个代码的结果相同.
This code is identical with the code above except I pass &x
to println!
. It prints '6' to the console which is correct and is the same result as the first code.
推荐答案
宏 print!
, println!
, eprint!
, eprintln!
、write!
、writeln!
和 format!
是特殊情况,隐式地引用任何参数进行格式化.
The macros print!
, println!
, eprint!
, eprintln!
, write!
, writeln!
and format!
are a special case and implicitly take a reference to any arguments to be formatted.
为了方便起见,这些宏的行为不像普通函数和宏;他们默默地接受引用的事实是这种差异的一部分.
These macros do not behave as normal functions and macros do for reasons of convenience; the fact that they take references silently is part of that difference.
fn main() {
let x = 5;
println!("{}", x);
}
在夜间编译器上通过 rustc -Z stable-options --pretty Expanded
运行它,我们可以看到 println!
扩展为:
Run it through rustc -Z unstable-options --pretty expanded
on the nightly compiler and we can see what println!
expands to:
#![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,
)],
},
));
};
}
进一步整理,是这样的:
Tidied further, it’s this:
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
.
If you write println!("{}", &x)
, you are then dealing with two levels of references; this has the same result because there is an implementation of std::fmt::Display
for &T
where T
implements Display
(shown as impl<'a, T> Display for &'a T where T: Display + ?Sized
) which just passes it through. You could just as well write &&&&&&&&&&&&&&&&&&&&&&&x
.
这篇关于是否 println!借用或拥有变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!