Associated types let a trait declare a type that implementors must define. This is cleaner than adding a generic parameter to the trait. For example, Iterator has an associated type Item rather than being Iterator<Item>. I use associated types when each implementation has exactly one logical choice for the type. They reduce syntactic noise and make trait bounds more readable. For example, T: Iterator<Item=u32> vs hypothetical T: Iterator<u32>. Associated types also enable impl Iterator return types without naming the item type. They're a key part of Rust's zero-cost abstraction story, making generic code both fast and ergonomic.