`IntoIterator` defines how a value becomes an iterator. For a collection, implement it separately for the owned value, a shared reference, and a mutable reference when those forms should yield different items. Keep iteration state in dedicated iterator types rather than implementing `Iterator` on the collection itself. section 3.2.4
impl<'a, T> IntoIterator for &'a LinkedList<T> {
type IntoIter = Iter<'a, T>;
type Item = &'a T;
fn into_iter(self) -> Self::IntoIter {
self.iter() #1
}
}
impl<'a, T> IntoIterator for &'a mut LinkedList<T> {
type IntoIter = IterMut<'a, T>;
type Item = &'a mut T;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut() #2
}
}
impl<T> IntoIterator for LinkedList<T> { #3
type IntoIter = IntoIter<T>;
type Item = T;
fn into_iter(self) -> Self::IntoIter {
self.into_iter() #4
}
}
The three `LinkedList` implementations delegate to `iter()`, `iter_mut()`, and `into_iter()`, yielding `&T`, `&mut T`, and `T` respectively. section 3.2.4
Iterate without consuming the list
`for data in &linked_list { ... }` uses the shared-reference implementation, so each `data` is a borrowed item. Use the owned form when iteration should consume the list. section 3.2.4
The return type matters: an initial linked-list implementation returned `Rc<RefCell<T>>` from all three iterator types, obscuring the intended ownership differences. Its consuming iterator instead tries to unwrap those shared pointers to yield `T`; that can fail when other owners remain. section 3.2.4
