I'm working through Learning Rust with Entirely Too Many Linked Lists and had a question about the drop implementation for the initial linked list from that book. The linked list is composed of a stack allocated link, which is either empty or points to a heap allocated Node with some associated data.
struct List {
head: Link,
}
enum Link {
Empty,
More(Box<Node>),
}
struct Node {
data: i32,
next: Link,
}
The implementation of the drop trait given in the book uses std::mem::replace to take ownership of the nodes in the list.
// Copied from the book, omitting comments
impl Drop for List {
fn drop(&mut self) {
let mut cur_link = mem::replace(&mut self.head, Link::Empty);
while let Link::More(mut boxed_node) = cur_link {
cur_link = mem::replace(&mut boxed_node.next, Link::Empty);
}
}
}
I'm confused why the book is using mem::replace to take ownership of the next pointer of the node. It seems like we already have owndership of boxed_node from the while let line and we can just set cur_link to node.next instead of using mem::replace.
I wrote this alternative implementation which compiles just fine. I'm wondering if there is any difference between the two drop methods.
impl Drop for List {
fn drop(&mut self) {
let mut link = mem::replace(&mut self.head, Link::Empty);
while let Link::More(node) = link {
link = node.next;
}
}
}