0

It's a habit of mine to implement a linked list in every new language I learn, so this is only an educational exercise. This list only keeps track of the head. While it's easy to push to the front of the list, I'm having difficulty implementing a push_back(). Here's a snippet of the code:

struct List<T> {
    head: Link<T>,
}

type Link<T> = Option<Box<Node<T>>>;

#[derive(Debug)]
struct Node<T> {
    data: T,
    next: Link<T>,
}

impl<T> List<T> {
    fn new() -> Self {
        List { head: None }
    }

    fn push_front(&mut self, data: T) {
        match self.head.take() {
            Option::None => {
                self.head = Some(Box::new(Node {
                    data: data,
                    next: None,
                }));
            }
            Option::Some(boxed_node) => {
                self.head = Some(Box::new(Node {
                    data: data,
                    next: Some(boxed_node),
                }));
            }
        };
    }

    fn push_back(&mut self, data: T) {
        let mut cur_link = &mut self.head;
        while let Some(ref mut boxed_node) = *cur_link {
            if boxed_node.next.is_none() {
                boxed_node.next = Some(Box::new(Node {
                    data: data,
                    next: None,
                }));
                break;
            }
            cur_link = &mut boxed_node.next;
        }
    }
}

On the Rust Playground

Compilation returns the following errors:

error[E0499]: cannot borrow `cur_link.0` as mutable more than once at a time
  --> src/main.rs:37:24
   |
37 |         while let Some(ref mut boxed_node) = *cur_link {
   |                        ^^^^^^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop
...
47 |     }
   |     - mutable borrow ends here

error[E0506]: cannot assign to `cur_link` because it is borrowed
  --> src/main.rs:45:13
   |
37 |         while let Some(ref mut boxed_node) = *cur_link {
   |                        ------------------ borrow of `cur_link` occurs here
...
45 |             cur_link = &mut boxed_node.next;
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `cur_link` occurs here

I'm finding the borrow checker unsympathetic with my need to borrow a node with each iteration, but only mutate it on the successive iteration.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
BrainCore
  • 5,214
  • 4
  • 33
  • 38
  • 3
    [Learning Rust With Entirely Too Many Linked Lists](http://cglab.ca/~abeinges/blah/too-many-lists/book/) – Shepmaster Dec 18 '17 at 23:33
  • [The duplicate applied to your problem](https://play.rust-lang.org/?gist=b54cd523029d907de87f40ae008513ef&version=stable) – Shepmaster Dec 19 '17 at 03:03

0 Answers0