在尝试实现一个向链表的元素生成可变引用的迭代器时,我偶然发现了一个奇怪的问题。
这很好用:
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
答案 0 :(得分:2)
请注意,对于代码的两个变体位,您已经省略了LinkedListMutIterator
的定义,这可能与重现和剖析问题的任何真实尝试相关。
所以,我会试着猜测发生了什么。
此处的编译器错误消息可能会误导您;除了self
的生命周期之外还有其他因素可能与此相关。
特别是我怀疑借用检查器是在抱怨,因为它试图确保你没有创建多个同义状态的多变量借用。
声音有多个不可变借用到同一个州......
...但是你不能对同一个状态进行多次可变借用(因为我们要确保如果你对某个状态有&mut
引用,那么该引用是唯一的改变国家的方式)。