2015-05-26 11 views
34

Jestem zdezorientowany z pożyczek i własności. W Rust documentation about reference and borrowingCzy println! pożyczyć lub posiadać zmienną?

let mut x = 5; 
{ 
    let y = &mut x; 
    *y += 1; 
} 
println!("{}", x); 

Mówią

println! może pożyczyć x.

Jestem zdezorientowany tym. Jeśli println! pożycza x, dlaczego przekazuje "x", a nie "& x"?

próbuję uruchomić ten kod poniżej

fn main() { 
    let mut x = 5; 
    { 
     let y = &mut x; 
     *y += 1; 
    } 
    println!("{}", &x); 
} 

ten kod jest identyczny z kodem powyżej, z wyjątkiem mijam „& X” aby println!. Wydaje "6" do konsoli, która jest poprawna i jest taki sam jak pierwszy kod.

Odpowiedz

34

Makra print!, println!, eprint!, eprintln!, write!, writeln! i format! stanowią szczególny przypadek, nie zachowuje się jak normalne rzeczy zrobić ze względu na wygodę. Fakt, że w milczeniu odbierają odniesienia, jest częścią tej różnicy.

fn main() { 
    let x = 5; 
    println!("{}", x); 
} 

go uruchomić poprzez rustc -Z unstable-options --pretty expanded na nocnej kompilator i możemy zobaczyć co println! rozszerza się:

#![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), 
       ] 
      } 
     }, 
    )); 
} 

uporządkowany dużo, to w ten sposób:

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)], 
    )); 
} 

Zanotuj &x.

Jeśli napiszesz println!("{}", &x), będziesz miał do czynienia z dwoma poziomami referencji; ma to taki sam skutek, ponieważ istnieje implementacja std::fmt::Display dla &T, gdzie T implementuje Display (pokazane jako impl<'a, T> Display for &'a T where T: Display + ?Sized), które właśnie ją przekazuje. Równie dobrze można napisać &&&&&&&&&&&&&&&&&&&&&&&x.

+0

Nie rozumiem, dlaczego nazwałbyś te makra "specjalnym przypadkiem". Ten rodzaj niejawnego przekazywania referencji może zostać zaimplementowany dla dowolnego makra. –

+4

@MarkusUnterwaditzer: Oczywiście, ale chodzi o to, że wygląda normalnie, ale nie jest. I oczywiście, inne makra również mogą stać się specjalnymi przypadkami. Faktem jest, że zdecydowanie odradza się go w ogóle. –

Powiązane problemy