Iterators and Drop
Implement Iterator three ways, and fix the stack overflow on drop.
A long list overflows the stack when dropped: each Nodeβs destructor drops the next one
recursively. Write it out iteratively:
impl<T> Drop for List<T> {
fn drop(&mut self) {
let mut cur = self.head.take();
while let Some(mut node) = cur {
cur = node.next.take();
}
}
}
Then three iterators, which is really three ways of expressing ownership:
| Type | Yields | Consumes the list? |
|---|---|---|
IntoIter |
T |
yes |
Iter<'a> |
&'a T |
no |
IterMut<'a> |
&'a mut T |
no |
IterMut is the one that surprises people β itβs safe, but only because the borrow checker
can prove you never hand out two &mut to the same node.