Does println! borrow or own the variable?

回眸只為那壹抹淺笑 提交于 2019-11-26 15:27:30
Chris Morgan

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.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!