I\'m trying to navigate a recursive data structure iteratively in order to insert elements at a certain position. To my limited understanding, this means taking a mutable re
It is possible... but I wish I had a more elegant solution.
The trick is NOT to borrow from anchor
, and therefore to juggle between two accumulators:
This leads me to:
impl Recursive {
fn back(&mut self) -> &mut Link {
let mut anchor = &mut self.root;
loop {
let tmp = anchor;
if let Some(ref mut node) = *tmp {
anchor = &mut node.next;
} else {
anchor = tmp;
break;
}
}
anchor
}
}
Not exactly pretty, but this is something the borrow checker can get behind so ¯\_(ツ)_/¯.
@ker has improved on this by creating an unnamed temporary:
impl Recursive {
fn back(&mut self) -> &mut Link {
let mut anchor = &mut self.root;
loop {
match {anchor} {
&mut Some(ref mut node) => anchor = &mut node.next,
other => return other,
}
}
}
}
The trick here is that using {anchor}
moves the content of anchor
into an unnamed temporary on which the match executes. Therefore, in the match
block we are not borrowing from anchor
but from the temporary, leaving us free to modify anchor
. See the related blog post Stuff the Identity Function Does (in Rust).