struct Node<T> {
content: T,
next: Option<Box<Node<T>>>
}
struct LinkedList<T> {
first: Option<Box<Node<T>>>,
size: i64
}
impl<T: std::default::Default + std::cmp::PartialEq> LinkedList<T> {
fn new() -> Self {
LinkedList { first: None, size: 0 }
}
fn push(&mut self, value: T) {
let mut tmp_node = Box::new(Node { content: value, next: None });
let old_first_node = std::mem::replace(&mut self.first, None);
tmp_node.next = old_first_node;
self.first = Some(tmp_node);
self.size += 1;
}
fn pop(&mut self) -> Option<T> {
let mut old_first = std::mem::replace(&mut self.first, None);
match &mut old_first {
None => {
return None;
},
Some(ptr) => {
self.first = std::mem::take(&mut ptr.next);
let val_to_return = std::mem::take(&mut ptr.content);
return Some(val_to_return);
}
}
}
fn remove(&mut self, value: T) {
let mut current_node = &mut self.first;
while let Some(node) = current_node {
if node.content == value {
*current_node = node.next.take();
break;
}
current_node = &mut node.next;
}
}
}
fn main() {
}
I tried to implement this function a lot but every solution I thought of, the compiler complains about some "borrow" error, in this case, the error is "cannot assign to *current_node because is borrowed". How can i avoid this error and make the current node be the next node of the linked list?
Actually, your code is correct, it's a limitation of the compiler that it doesn't accept it. It is accepted with the nightly Polonius borrow checker.
The simplest solution is to replace while let
with is_some()
and unwrap()
s:
fn remove(&mut self, value: T) {
let mut current_node = &mut self.first;
while current_node.is_some() {
if current_node.as_mut().unwrap().content == value {
*current_node = current_node.as_mut().unwrap().next.take();
break;
}
current_node = &mut current_node.as_mut().unwrap().next;
}
}