I'd implementing a simple linked list. This is the (working) code I had so far:
pub struct LinkedList<T> {
start: Option<Box<Link<T>>>,
}
impl<T> LinkedList<T> {
pub fn new() -> LinkedList<T> {
return LinkedList { start: None };
}
}
struct Link<T> {
value: Box<T>,
next: Option<Box<Link<T>>>,
}
impl<T> Link<T> {
fn new_end(value: T) -> Link<T> {
return Link::new(value, None);
}
fn new(value: T, next: Option<Box<Link<T>>>) -> Link<T> {
return Link {
value: Box::new(value),
next,
};
}
}
Next on the list is a method to append to the list; this is what I came up with:
pub fn append(&mut self, element: T) {
// Create the link to append
let new_link = Some(Box::new(Link::new_end(element)));
// Find the last element of the list. None, if the list is empty
let mut last = &self.start;
while let Some(link) = last {
last = &link.next;
}
// Insert the new link at the correct position
match last {
None => self.start = new_link,
Some(last) => last.next = new_link, // This fails
}
}
The precise compiler error is
error[E0594]: cannot assign to `last.next` which is behind a `&` reference
I vaguely get the problem; you cannot mutate an immutable reference. But making the references mutable does seem to make the errors even worse.
How does one handle these kinds of errors? Is there a simple quick-fix, or do you structure your code completely different in Rust?
Your code almost worked. It will if you bind mutably:
impl<T> LinkedList<T> {
pub fn append(&mut self, element: T) {
// Create the link to append
let new_link = Some(Box::new(Link::new_end(element)));
// Find the last element of the list. None, if the list is empty
let mut last = &mut self.start;
while let Some(link) = last {
last = &mut link.next;
}
// Insert the new link at the correct position
match last {
None => self.start = new_link,
Some(ref mut last) => last.next = new_link,
}
}
}
FYI, the answer to this recent question is very good at clarifying the matter about mutability, type and binding in Rust.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With