2016-06-17 9 views
3

錆についてはchecking out tutorialsですが、私は借用チェッカーに問題が発生しました。次のコードはコンパイルされません:Rustコンパイラに借用が終了したことを伝えるには?

struct Car { 
    model: String, 
} 

struct Person<'a> { 
    car: Option<&'a Car>, 
} 

impl<'a> Person<'a> { 
    fn new() -> Person<'a> { 
     Person { car: None } 
    } 

    fn buy_car(&mut self, c: &'a Car) { 
     // how to say that Person don't borrow the old car any longer? 
     self.car = Some(c); 
    } 
} 

fn main() { 
    let civic = Car { model: "Honda Civic".to_string() }; 
    let mut ghibli = Car { model: "Maserati Ghibli".to_string() }; 
    let mut bob = Person::new(); 

    bob.buy_car(&ghibli); 

    bob.buy_car(&civic); 

    // error: cannot borrow `ghibli` as mutable because it is also borrowed as immutable 
    let anything = &mut ghibli; 
} 

を、私はそれのためには、錆のボローチェッカーがghibliのボローがすでに終了していることを認識することができない、語彙自然だということを理解しています。

しかし、私は本当にこの問題を解決する方法を知りたいですか?何らかの形でRc<T>またはBox<T>を使用する必要がありますか?

答えて

2

これは、静的な借用規則が機能しない場合です。これは、コンパイラに伝えることができない動的な動作が起こっているためです。

実行時に借用チェックを行うことができるRc<T>を使用する必要があります。または変更可能なアクセスが必要な場合は、Rc<Cell<T>>またはRc<RefCell<T>>です。そして、あなたが動的に安全な方法でそれにアクセスする限り、すべてがうまくいくでしょう。

2

終了ボローが新しいスコープを導入することであるボロー・チェッカーを伝えるために「錆の方法は、」:

fn main() { 
    let civic = Car{model: "Honda Civic".to_string()}; 
    let mut ghibli = Car{model: "Maserati Ghibli".to_string()}; 
    { 
     let mut bob = Person::new(); 

     bob.buy_car(&ghibli); 

     bob.buy_car(&civic); 
    } 
    let anything = &mut ghibli; 
} 

はあなたがが実現しなければならないものを、あなたの例では、(おそらくではということですとにかく)ほとんどの場合、借りチェッカーは正しかった。

Bobghibliへの参照を借りてください。彼のcarフィールドのメインメソッドの最後にはまだ存在します。

+4

いいえ: 'bob.buy_car(&civic)'は 'car'フィールドを上書きします。だから、借用チェッカーは "間違っている" ...私はそれがとても簡単だと思うが、間違っている。 –

+1

ああ。はい、もちろん、あなたは正しいです。それを見落とさなければならない。 @MatthieuM。 – JDemler

+1

。私の理解は、借用チェッカーはメソッドの内部を見ていない、それは宣言だけを見ています。たとえば、コンパイルされたライブラリのメソッドを使用することを考えてください。ソースコードはありません。 – hamstergene

関連する問題