Beim Versuch, einen Iterator zu implementieren, der veränderbare refs zu Elementen einer verknüpften Liste ergibt, stolperte ich über ein seltsames Problem.Borrow vs veränderbar borgen seltsamen Fehler in Lebenszeiten
Dies funktioniert:
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
}
}
}
Aber das funktioniert nicht; der Compiler sagt Lebensdauer von self
zu kurz ist, seinen Inhalt zu gewährleisten sicher neu aufgenommen werden kann:
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
}
}
}
Ich würde erwarten, dass entweder beide beispielsweise Arbeit oder beides nicht, aber ich kann nicht verstehen, wie Kreditaufnahme etwas wie wandelbar vs not-mutable würde die Art beeinflussen, wie der Compiler nach Lebensdauern sucht. Sicherlich, wenn etwas lange genug lebt, um sicher ausgeliehen zu werden, lebt es lange genug, um sicher umwandelbar geliehen zu werden?
EDIT: Hier ist die Definition der beiden Iteratoren:
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
}
für eine komplette Ansicht der Datei finden Sie in https://github.com/TisButMe/rust-algo/blob/mut_iter/LinkedList/linked_list.rs
Die von Ihnen vorgeschlagenen Informationen hinzugefügt. Ich sehe nicht, wo ich anderswo xs irgendwo anders leihen kann? Der einzige andere & mut-Zeiger ist der in der Struktur gespeicherte Zeiger _current_, der auf das vorherige Element in der Liste zeigt, nicht auf xs. –
Ich denke, ein Beweis, dass der Iterationscode jede Zelle der Linked-List * höchstens einmal * besucht, übersteigt die Fähigkeiten des Border-Checkers. Sie und ich wissen, dass "next" den Cursor des Iterators in die verknüpfte Liste bringt und somit sicherstellt, dass Sie nicht denselben '& mut' Zeiger zweimal von" next "zurückgeben (was Alias illegal einführen würde), aber ich denke nicht der Borrow-Checker kann auf diese Weise argumentieren ... aber ich habe den Umgang des Borrow-Checkers mit diesem Fall noch nicht genau verfolgt. – pnkfelix
Einverstanden. Gibt es eine Möglichkeit, das zu umgehen, ohne unsichere Zeiger zu verwenden? –