2017-03-06 6 views
2

self値に含まれる値に変更可能な参照を返すルックアップ関数を実装しようとしています。通常、返された参照はlookupの外にあるデータ(self.verts)を指しているので、貸借チェッカーはそれに問題がないと見なします。私の場合は、参照を返して新しい所有の名前にバインドする前にself.vertsをフィルタリングしています。外部参照のフィルタリングされたベクトルへの参照を返すときに貸借チェッカーを解消する方法

error: `vs` does not live long enough 
    --> src/util/graph.rs:18:37 
    | 
18 |   if vs.len() > 0 { Some(&mut vs[0]) } else { None } 
    |          ^^ does not live long enough 
19 |  } 
    |  - borrowed value only lives until here 
    | 
note: borrowed value must be valid for the lifetime 'a as defined on the body at 16:75... 
    --> src/util/graph.rs:16:76 
    | 
16 |  pub fn lookup_id<'a>(&'a mut self, id: &str) -> Option<&'a mut Vertex> { 
    | ____________________________________________________________________________^ starting here... 
17 | |   let vs:Vec<&mut Vertex> = self.verts.iter_mut().filter(|x| x.id == id).collect(); 
18 | |   if vs.len() > 0 { Some(&mut vs[0]) } else { None } 
19 | |  } 
    | |_____^ ...ending here 

私はローカルに所有するコンテンツへの参照を返すことができないことを理解し、私は、コンパイラがどのようにそれがある疑いがある:私はそのローカルに所有している配列から値を返すようにしようとすると私は、コンパイル時エラーが発生します私のコードを解釈することですが、それは私がしたいことではありません。何がしたいのは、self.vertsベクトルの値への参照を返し、返された参照の寿命が同じで、参照が実行されている構造体を返すことです。ここに私の現在の試みは、次のとおりです。

pub fn lookup_id<'a>(&'a mut self, id: &str) -> Option<&'a mut Vertex> { 
    let vs:Vec<&'a mut Vertex> = self.verts.iter_mut().filter(|x| x.id == id).collect(); 
    if vs.len() > 0 { Some(&mut vs[0]) } else { None } 
} 

vs does not live long enoughので、このコードはコンパイルされません。コンパイラに、への参照ではなく、vsに含まれる参照を返すように指示するにはどうすればよいですか?

答えて

2

あなたは&mut &mut Vertexを返します。

あなたは残りの要素を破棄している場合は、怠惰な計算を行うことができます。 self.verts.iter_mut().filter(|x| x.id == id).next()

0

私は&mut &mut Vertexのようなものを疑いました。残念ながら、&mutの前にvsがなければ、他にもいくつかのコンパイラエラーがありました。判明したように、Rustはインデックス作成時に参照を返します。私が知らなかったものです。私はstd::vecモジュールをチェックしなければならず、remove()が値を直接返すことが分かった。このコードは動作します:

pub fn lookup_id(&mut self, id: &str) -> Option<&mut Vertex> { 
    let mut vs:Vec<&mut Vertex> = self.verts.iter_mut().filter(|x| x.id == id).collect(); 
    if vs.len() > 0 { Some(vs.remove(0)) } else { None } 
} 

このバージョンでは、しかし、非常にきれいである:

pub fn lookup_id(&self, id: &str) -> Option<&Vertex> { 
    self.verts.iter().find(|x| x.id == id) 
} 
関連する問題