2015-01-16 4 views
1
fn t(x: &mut u8) -> &mut u8 { 
    x 
} 

fn main() { 
    let mut x = 5u8; 
    let y = & mut x; 
    let z = t(y); 
    println!("{}", y); 
} 

Компиляция это дает мне эту ошибку:Ссылка передается в качестве параметра не перемещается

main.rs:9:20: 9:21 error: cannot borrow `y` as immutable because `*y` is also borrowed as mutable 
main.rs:9  println!("{}", y); 

Я бы подумал y бы было перемещено во время вызова t, а затем обратно в z, в результате чего error: use of moved value

  1. Почему вместо этого возникает это сообщение об ошибке?
  2. Rust автоматически создает новый заимствован вместо передачи права собственности, когда ссылки предлагаются в качестве параметров функции?
  3. Какова цель этого поведения?
+0

Смотрите также [Moving mutably заимствованные собственности] (http://stackoverflow.com/q/27650188/155423) – Shepmaster

ответ

3

Вы возвращаете изменяемую ссылку на параметр из своей функции. Однако Rust не знает, что метод не сохранил копию этого указателя не вернул подраздел этого указателя, была ли это структурой. Это означает, что в любое время указанное значение может быть изменено, что является большим нет-нет в Rust; если это разрешено, то вы можете легко вызвать ошибки памяти.

Does Rust automatically create a new borrow

Да, ржавчина «повторно забирает» ссылки.

Лучшего примера требует smidge больше сложности:

struct Thing { a: u8, b: u8 } 

fn t(x: &mut Thing) -> &mut u8 { 
    &mut x.a 
} 

fn main() { 
    let mut x = Thing { a: 5, b: 6 }; 
    let z = t(&mut x); 
    *z = 0; 
    // x.a = 0; // cannot assign to `x.a` because it is borrowed 
} 

Здесь t возвращает изменяемый указатель на подмножество структуры. Это означает, что вся структура заимствована, и мы не можем ее изменить (кроме z). Rust применяет эту логику ко всем функциям и не пытается распознать, что ваша функция t возвращает тот же указатель.

+0

'Rust не знает, что метод не сохранил копию этого указателя'. Поскольку функция истекла, не могла ли она объяснить, что что-нибудь в ней будет освобождено после ее вызова? –

+1

Подпись 't' заставляет заимствовать' y', если существует 'z'. И 'z' существует до конца' main'. – PEPP

+0

@JV Я обновил ответ и удалил вводящую в заблуждение часть, которую вы цитировали. – Shepmaster

0

При компиляции программы с rustc --pretty=expanded, мы можем видеть, что println! макрос заимствует свой аргумент:

#![no_std] 
#[macro_use] 
extern crate "std" as std; 
#[prelude_import] 
use std::prelude::v1::*; 
fn t(x: &mut u8) -> &mut u8 { x } 

fn main() { 
    let mut x = 5u8; 
    let y = &mut x; 
    let z = t(y); 
    ::std::io::stdio::println_args(::std::fmt::Arguments::new({ 
                    #[inline] 
                    #[allow(dead_code)] 
                    static __STATIC_FMTSTR: 
                     &'static [&'static str] 
                     = 
                     &[""]; 
                    __STATIC_FMTSTR 
                   }, 
                   &match (&y,) { // <----- y is borrowed here 
                    (__arg0,) 
                    => 
                    [::std::fmt::argument(::std::fmt::String::fmt, 
                         __arg0)], 
                   })); 
} 
Смежные вопросы