リンクされたリストの要素への変更可能な参照を生成する反復子を実装しようとしているときに、奇妙な問題に遭遇しました。
これはうまくいきます:
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
短すぎて、内容を安全に再借用できることを保証できないと言います:
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
}
}
}
両方の例が機能するか、または両方が機能しないことを期待しますが、変更可能と変更不可として何かを借用すると、コンパイラが寿命をチェックする方法にどのように影響するか理解できません。確かに何かが安全に借用できるほど長生きするなら、それは安全に可変的に借用できるほど長生きするでしょうか?
編集: 両方のイテレータの定義は次のとおりです。
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を参照してください。