14
IterMut
IterMut looks like Iter with &mut everywhere. It is not. Mutable references are not Copy — at any moment there is exactly one. To advance the cursor we have to move the current &mut Node out, take its next field, and put the new reference back. The tool for that is Option::take.
- Type and constructor mirror
Iter.as_deref_mutis the&mutcounterpart ofas_deref:Option<Box<Node<T>>> -> Option<&mut Node<T>>.pub struct IterMut<'a, T> { next: Option<&'a mut Node<T>>, } impl<T> List<T> { pub fn iter_mut(&mut self) -> IterMut<'_, T> { IterMut { next: self.head.as_deref_mut() } } } - The body of
nextcannot readself.nextand then assign to it — the read would be a copy of a&mut, which is forbidden.Option::takeswapsself.nextwithNone, handing us the inner&mut Nodeby value. We then split it into&mut node.elem(returned) andnode.next.as_deref_mut()(stored back intoself.next).impl<'a, T> Iterator for IterMut<'a, T> { type Item = &'a mut T; fn next(&mut self) -> Option<&'a mut T> { self.next.take().map(|node| { self.next = node.next.as_deref_mut(); &mut node.elem }) } } - Two things make this safe. First, each yielded
&mut Tborrows from a different node, so the references handed out across calls don't alias. Second, we only ever hold one cursor at a time — thetakeenforces that. The compiler verifies all of this without anunsafekeyword.let mut list = List::new(); list.push(1); list.push(2); list.push(3); for v in list.iter_mut() { *v *= 10; } assert_eq!(list.pop(), Some(30)); assert_eq!(list.pop(), Some(20)); assert_eq!(list.pop(), Some(10));