I thought I'd dive into Rust by imeplementing some very simple structure & algorithms, I started with a linked list. Turns out it's not actually that simple. This is my code so far:
enum List<T>
{
Node(T, ~List<T>),
Nil
}
impl<T> List<T>
{
fn new(vector: &[T]) -> List<T> { Nil }
fn add(&mut self, item: T)
{
let tail = self;
loop
{
match *tail
{
Node(_, ~ref next) => tail = next,
Nil => break
}
}
*tail = Node(item, ~Nil);
}
}
This won't compile because next cannot be assigned to tail in the match statement due to incompatible mutability. I know this can easily be done using garbage collected pointers, but that kind of defeats the educational purpose of the exercise: I'd like to know how to do this without Gc or Rc pointers.
It is difficult to implement Linked List in Rust as what is allowed in most languages is simply not allowed in Rust, While it may seem to be a little difficult but the Rust compiler also at the same time makes sure that your code is memory safe.
This is because Rust likes all of your memory to have one clear owner. And this means that cyclic data structures are unusually difficult compared to almost any other first program you might choose.
You have to start at the “head” of the list & follow the links until you find the node you want or until the end of the list. Removing (or adding) an item from the middle of a linked list is a lot faster. All you have to do is change the “next” pointer for one node.
It looks like you're trying to walk your own list to find the final element, but you don't actually have a loop. Assuming you fix that, your issue with mutability can be fixed by using ref mut
instead of ref
.
To try it myself I used a recursive implementation of add()
and this works:
fn add(&mut self, item: T) {
match *self {
Node(_, ref mut next) => next.add(item),
Nil => *self = Node(item, ~Nil)
}
}
Offhand I'm not sure how to implement this using an iterative approach, due to issues with mutable borrowing.
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