I want to create a simple linked list and add a value into it. How should the add method be implemented to make this code output 100 50 10 5 at lin
This is how you need to write it (playground link)
fn add(&mut self, node: Node) {
let item = Some(Box::new(node));
let mut current = self;
loop {
match moving(current).next {
ref mut slot @ None => {
*slot = item;
return;
}
Some(ref mut next) => current = next,
};
}
}
Ok, so what is this?
Step 1, we need to return immediately after using the value item. Then the compiler correctly sees that it is only moved from once.
ref mut slot @ None => {
*slot = item;
return;
}
Step 2, to loop with a &mut pointer that we update along the way is tricky.
By default, Rust will reborrow a &mut that is dereferenced. It doesn't consume the reference, it just considers it borrowed, as long as the product of the borrow is still alive.
Obviously, this doesn't work very well here. We want a “hand off” from the old current to the new current. We can force the &mut pointer to obey
move semantics instead.
We need this (the identity function forces move!):
match moving(current).next
we can also write it like this:
let tmp = current;
match tmp.next
or this:
match {current}.next
Step 3, we have no current pointer after we looked up inside it, so adapt the code to that.
ref mut slot to get a hold on the location of the next value.