Прежде чем начать, прочитайте Изучение ржавчины со слишком большим количеством связанных списков . Люди думают, что связанные списки просты , потому что их учили на языках, которые либо не заботятся о том, что вы вводите небезопасную память, либо полностью лишаете это агентство программиста.
Ржавчина не делает ни того, ни другого, а это значит, что вы должны думать о вещах, о которых вы, возможно, никогда раньше не думали.
Есть ряд проблем с вашим кодом. Тот, о котором вы спрашиваете, «не может выйти из заимствованного контента», уже хорошо охвачен множеством других вопросов, поэтому нет причин повторять все эти хорошие ответы:
TL; DR: вы пытаетесь переместить владение next
из ссылки; ты не можешь.
p.next = c.next;
Вы пытаетесь изменить неизменяемую ссылку:
let mut head = &self.head;
Вы позволяете людям убрать один конец конца, что не имеет смысла для меня:
if index >= self.len()
Вы итерируете все дерево не один раз, а дважды , прежде чем повторять его снова, чтобы выполнить удаление:
if self.len() == 0
if index >= self.len()
Все это меркнет по сравнению с тем фактом, что ваш алгоритм некорректен в глазах Rust, потому что вы пытаетесь ввести изменяемый псевдоним . Если бы ваш код мог компилироваться, у вас была бы изменяемая ссылка на previous
, а также изменяемая ссылка на current
. Однако, вы можете получить изменяемую ссылку на current
из previous
. Это позволит вам нарушить гарантии безопасности памяти Rust!
Вместо этого вы можете отслеживать только current
и, когда правильный индекс найден, разбить его на части и разложить кусочки:
fn remove(&mut self, index: usize) -> T {
self.remove_x(index)
.unwrap_or_else(|| panic!("index {} out of range", index))
}
fn remove_x(&mut self, mut index: usize) -> Option<T> {
let mut head = &mut self.head;
while index > 0 {
head = match { head }.as_mut() {
Some(n) => &mut n.next,
None => return None,
};
index -= 1;
}
match head.take().map(|x| *x) {
Some(Node { data, next }) => {
*head = next;
Some(data)
}
None => None,
}
}
Смотри также:
Playground Link для получения дополнительной информации.
Есть множество проблем с остальным кодом, например, тот факт, что результат вашего insert
метода не похож ни на один, который я когда-либо видел.
Как бы я это написал .