Challenge 3: The Three Iteration Styles, Explained — Possible Solution ==================================================================== .iter() — yields &T (immutable references) for each element. The original collection is BORROWED, not consumed — it remains fully valid and usable after the iteration completes, since nothing about ownership ever changed hands. This is the right default choice when you only need to READ each element. .iter_mut() — yields &mut T (mutable references) for each element, letting the loop body modify elements IN PLACE. Like .iter(), this is still a borrow (a mutable one, per Chapter 4's borrow rules) — the collection itself remains valid and usable afterward; only its elements' VALUES may have changed, not its ownership status. .into_iter() (or a bare `for x in vec`, which uses into_iter() implicitts under the hood) — yields OWNED T values, meaning it CONSUMES the collection entirely. Per Chapter 3's move semantics, the original Vec (or HashMap) is MOVED into the iteration process and is NO LONGER USABLE afterward — attempting to reference it again after a bare `for x in vec { ... }` loop produces a "value moved" compile error, the exact same error category Chapter 3 introduced for any other moved value. THE KEY DISTINCTION: .iter() and .iter_mut() BORROW (collection survives); .into_iter() / bare `for x in vec` MOVES (collection is gone afterward) — a genuinely Rust-specific consideration with no real equivalent in Go or JavaScript, where iterating a slice/array never affects its usability afterward at all.