2016-10-20 3 views
2

私は錆のある場所で再帰的なパーサーを実装していますが、いくつかの借用エラーが発生しています。それはこれが私に次のエラー与え複数の借用のエラーを借用

use std::vec::Vec; 

struct MyBorrows<'a> { 
    val : &'a mut i32 
} 

impl <'a> MyBorrows<'a> { 
    fn new(v : &'a mut i32) -> MyBorrows<'a> { 
     MyBorrows { val : v } 
    } 
} 

fn main() { 
    let mut my_val = 23; 
    let mut my_vec : Vec<Box<MyBorrows>> = Vec::new(); 
    my_vec.push(Box::new(MyBorrows::new(&mut my_val))); 
    for i in [1..4].iter() { 
     let mut last : &mut Box<MyBorrows> = my_vec.last_mut().unwrap(); 
     let mut new_borrow = Box::new(MyBorrows::new(last.val)); 
     my_vec.push(new_borrow);   
    } 
} 

非常に有用ではありませんが、コードスニペットは、問題を再現:私の本当の場合

 
error[E0499]: cannot borrow `my_vec` as mutable more than once at a time 
    --> test.rs:20:9 
    | 
18 |   let mut last : &mut Box = my_vec.last_mut().unwrap(); 
    |            ------ first mutable borrow occurs here 
19 |   let mut new_borrow = Box::new(MyBorrows::new(last.val)); 
20 |   my_vec.push(new_borrow); 
    |   ^^^^^^ second mutable borrow occurs here 
21 |  } 
22 | } 
    | - first borrow ends here 

error: aborting due to 3 previous errors 

を、ベクトルは深く深くを参照するために、スタックとして使用されていますstructのコンポーネント私は解析しています。これは私がRustで複製しようとしているC++の一般的な解析に使用する一般的なパターンですが、問題があります。どんな助けもありがとう。

答えて

3

あなたがしようとしていることは不健全です。 MyBorrowsを複数作成しようとしていて、すべて同じ値を別々に借りて、一度に(ベクトル内に)生きているようです。そのような設定は、まさにRustがデータ競合の発生を防ぐために設計したものです。

代わりに何をしたいのですか。imは合法的に値を束ねています。あなたは今、わずかに異なるエラーが出る

struct MyBorrows<'a> { 
    val : &'a i32 
} 

impl <'a> MyBorrows<'a> { 
    fn new(v : &'a i32) -> MyBorrows<'a> { 
     MyBorrows { val : v } 
    } 
} 

fn main() { 
    let my_val = 23; 
    let mut my_vec = vec![]; 
    my_vec.push(Box::new(MyBorrows::new(&my_val))); 
    for _ in 1..4 { 
     let last = my_vec.last().unwrap(); 
     let new_borrow = Box::new(MyBorrows::new(last.val)); 
     my_vec.push(new_borrow); 
    } 
} 

error[E0502]: cannot borrow `my_vec` as mutable because it is also borrowed as immutable 
    --> test.rs:18:9 
    | 
16 |   let last = my_vec.last().unwrap(); 
    |     ------ immutable borrow occurs here 
17 |   let new_borrow = Box::new(MyBorrows::new(last.val)); 
18 |   my_vec.push(new_borrow); 
    |   ^^^^^^ mutable borrow occurs here 
19 |  } 
    |  - immutable borrow ends here 

error: aborting due to previous error 

この1はトリッキーで、あなたは何を実現する必要がありますので、不必要な可変借りを掃除した後、私はに、問題を低減しましたmy_vec.last()に電話すると、Vecの既存のメモリへの参照が返され、Vecに触れることができなくなります。現在、Rustでは、この参照は現在のブロックの最後まで存続します。これを回避するために、独自のブロックスコープで可変ボローを包む:プッシュが発生する前に

fn main() { 
    let my_val = 23; 
    let mut my_vec = vec![]; 
    my_vec.push(Box::new(MyBorrows::new(&my_val))); 
    for _ in 1..4 { 
     let new_borrow; 
     { 
      let last = my_vec.last().unwrap(); 
      new_borrow = Box::new(MyBorrows::new(last.val)); 
     } 
     my_vec.push(new_borrow); 
    } 
} 

は今可変ボローが終了し、寿命が働きます。うまくいけば、将来、we will get non-lexical lifetimesが言語に追加されたので、コンパイラは私の最初の例が実際に安全であることを理解することができます。

関連する問題