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);
They say
println!can borrowx.
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);
}
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.
The macros print!, println!, eprint!, eprintln!, write!, writeln! and format! are a special case, not behaving as normal things do for reasons of convenience. The fact that they take references silently is part of that difference.
fn main() {
let x = 5;
println!("{}", x);
}
Run it through rustc -Z unstable-options --pretty expanded on the nightly compiler and we can see what println! expands to:
#![feature(prelude_import)]
#![no_std]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std as std;
fn main() {
let x = 5;
::io::_print(::std::fmt::Arguments::new_v1(
{
static __STATIC_FMTSTR: &'static [&'static str] = &["", "\n"];
__STATIC_FMTSTR
},
&match (&x,) {
(__arg0,) => {
[
::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Display::fmt),
]
}
},
));
}
Tidied a lot, it’s this:
use std::fmt;
use std::io;
fn main() {
let x = 5;
io::_print(fmt::Arguments::new_v1(
&["", "\n"];
&[fmt::ArgumentV1::new(&x, fmt::Display::fmt)],
));
}
Note the &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.
来源:https://stackoverflow.com/questions/30450399/does-println-borrow-or-own-the-variable