danics
danics

Reputation: 323

Custom link list pop_back implementation

I'm new to rust and try to understand &mut ref variables and mutability. I started creating a simple link list with pop_back function.

pub fn pop_back(&mut self) -> Option<T> {
        let mut head = &mut self.head;
        while let Some(v) = head {
            if v.next.is_none() {
                break;
            }
            head = &mut v.next;
        }
        head.take().map(|node| node.data)
    }

but can't make it to work. error is cannot borrow *head as mutable more than once at a time. How can I tell rust that I want to only change the reference in my loop not the value? I don't want to add another tail variable to my list so without changing structure how can I make this work?

this is the struct definition

pub struct Node<T> {
    data: T,
    next: Option<Box<Node<T>>>
}

pub struct SimpleLinkedList<T> {
    head: Option<Box<Node<T>>>,
}

Upvotes: 1

Views: 95

Answers (1)

Chayim Friedman
Chayim Friedman

Reputation: 71300

This is a known limitation of the borrow checker. The next-gen Polonius will solve this.

In the meantime, the solution (without unsafe) is to repeat the calculation. In your case, this means some unwrap()s:

pub fn pop_back(&mut self) -> Option<T> {
    let mut head = &mut self.head;
    while head.is_some() {
        if head.as_mut().unwrap().next.is_none() {
            break;
        }
        head = &mut head.as_mut().unwrap().next;
    }
    head.take().map(|node| node.data)
}

See also:

Upvotes: 2

Related Questions