打印!借用或拥有变量?
Does println! borrow or own the variable?
我对借用和所有权感到困惑。在 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)
,你就是在处理两层引用;这具有相同的结果,因为 &T
有一个 std::fmt::Display
的实现,其中 T
实现 Display
(显示为 impl<'a, T> Display for &'a T where T: Display + ?Sized
),它只是通过它。你也可以写 &&&&&&&&&&&&&&&&&&&&&&&x
.
我对借用和所有权感到困惑。在 Rust documentation about reference and borrowing
let mut x = 5;
{
let y = &mut x;
*y += 1;
}
println!("{}", x);
他们说
println!
can borrowx
.
我对此感到困惑。如果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)
,你就是在处理两层引用;这具有相同的结果,因为 &T
有一个 std::fmt::Display
的实现,其中 T
实现 Display
(显示为 impl<'a, T> Display for &'a T where T: Display + ?Sized
),它只是通过它。你也可以写 &&&&&&&&&&&&&&&&&&&&&&&x
.