雖然試圖實現一個產生可變引用鏈接列表元素的迭代器,但我偶然發現了一個奇怪的問題。借用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不可變會影響編譯器檢查生命週期的方式。當然,如果有足夠長的時間可以安全借用,它的壽命足夠長,以便能夠安全地進行可變借用?
編輯:這裏是兩個迭代器的定義:
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'指針(這會引入非法的混淆),但我不認爲借款支票可以這種方式推理......但我還沒有仔細檢查借款支票對此案件的處理情況。 – pnkfelix
同意。那麼有沒有什麼辦法可以避免使用不安全的指針呢? –