リンクリストの要素に対する変更可能な参照を生成するイテレータを実装しようとしているとき、私は奇妙な問題に遭遇しました。借用vs変更可能生涯で奇妙な借用
これは正常に動作します:
impl<'a, T> Iterator<&'a T> for LinkedListIterator<'a, T>{
fn next(&mut self) -> Option<&'a T> {
match self.current {
&Cell(ref x, ref xs) => {self.current = &**xs; Some(x)},
&End => None
}
}
}
しかし、これは動作しません。コンパイラはself
の寿命が安全にreborrowedすることができ、その内容を保証するには短すぎると言う:
impl<'a, T> Iterator<&'a mut T> for LinkedListMutIterator<'a, T>{
fn next(&mut self) -> Option<&'a mut T> {
match self.current {
&Cell(ref mut x, ref mut xs) => {self.current = &mut **xs; Some(x)},
&End => None
}
}
}
私は両方の例の仕事のどちらか、または両方がないことを期待するだろうが、私は理解することはできませんどのように借入何かのように変更可能vs not-mutableは、コンパイラが存続期間をチェックする方法に影響します。確かに何かが安全に借りるのに十分な長さであれば、それは安全に変更可能に借りられるほど長く生きるのですか?
EDIT:
pub struct LinkedListIterator<'a, T>
current: &'a LinkedList<T>
}
pub struct LinkedListMutIterator<'a, T> {
current: &'a mut LinkedList<T>
}
LinkedLisk:ファイルの完全なビューのために
#[deriving(Eq, Clone)]
pub enum LinkedList<T> {
Cell(T, ~LinkedList<T>),
End
}
、あなたがきたhttps://github.com/TisButMe/rust-algo/blob/mut_iter/LinkedList/linked_list.rs
あなたが提案した情報を追加しました。 私はどこにxsをどこからでも借りていますか?唯一の他の&mutポインタは、構造体に格納されている_current_ポインタです。ポインタはxsではなくリストの前の要素を指します。 –
私は、反復コードがリンクリスト*の各セルをたびたび訪問するという証拠は、借用チェッカーの機能を超えていると思います。あなたと私は 'next'がイテレータのカーソルをリンクリストに更新し、' next'から同じ '&mut'ポインタを2回返さないことを保証しています(違法にエイリアシングを導入するでしょう)借りチェッカーはそのように考えることができます...しかし、私は借りチェッカーがこのケースを慎重に処理していることをまだ追跡していません。 – pnkfelix
合意。安全でないポインタを使用しないで回避する方法はありますか? –