Files
leonardomso__rust-skills/rules/name-iter-method.md
T
Leonardo Maldonado 0016d5cfb2 Add comprehensive Rust best practices skill with 179 rules
Includes rules for:
- Ownership and borrowing patterns
- Error handling with thiserror/anyhow
- Memory management and allocation
- API design following Rust guidelines
- Async/Tokio patterns
- Performance optimization
- Naming conventions
- Type safety
- Testing strategies
- Documentation standards
- Project structure
- Linting configuration
- Common anti-patterns to avoid
2026-01-19 10:23:19 -03:00

3.3 KiB

name-iter-method

Name iterator methods iter(), iter_mut(), and into_iter() consistently

Why It Matters

Rust has a strong convention for iterator method names. Following these conventions makes your types work predictably with for loops and iterator adapters. Users expect iter() for shared references, iter_mut() for mutable references, and into_iter() for owned iteration.

Bad

struct Collection<T> {
    items: Vec<T>,
}

impl<T> Collection<T> {
    // Non-standard names - confusing
    fn elements(&self) -> impl Iterator<Item = &T> {
        self.items.iter()
    }
    
    fn get_iterator(&self) -> impl Iterator<Item = &T> {
        self.items.iter()
    }
    
    fn to_iter(self) -> impl Iterator<Item = T> {
        self.items.into_iter()
    }
}

Good

struct Collection<T> {
    items: Vec<T>,
}

impl<T> Collection<T> {
    /// Returns an iterator over references.
    fn iter(&self) -> impl Iterator<Item = &T> {
        self.items.iter()
    }
    
    /// Returns an iterator over mutable references.
    fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
        self.items.iter_mut()
    }
}

// Implement IntoIterator for for-loop support
impl<T> IntoIterator for Collection<T> {
    type Item = T;
    type IntoIter = std::vec::IntoIter<T>;
    
    fn into_iter(self) -> Self::IntoIter {
        self.items.into_iter()
    }
}

impl<'a, T> IntoIterator for &'a Collection<T> {
    type Item = &'a T;
    type IntoIter = std::slice::Iter<'a, T>;
    
    fn into_iter(self) -> Self::IntoIter {
        self.items.iter()
    }
}

impl<'a, T> IntoIterator for &'a mut Collection<T> {
    type Item = &'a mut T;
    type IntoIter = std::slice::IterMut<'a, T>;
    
    fn into_iter(self) -> Self::IntoIter {
        self.items.iter_mut()
    }
}

Iterator Convention Summary

Method Receiver Yields Use Case
iter() &self &T Read-only iteration
iter_mut() &mut self &mut T In-place modification
into_iter() self T Consuming iteration

For Loop Integration

let col = Collection { items: vec![1, 2, 3] };

// These all work with proper IntoIterator impls
for item in &col {           // Calls (&col).into_iter() -> iter()
    println!("{}", item);    // &i32
}

for item in &mut col {       // Calls (&mut col).into_iter() -> iter_mut()
    *item += 1;              // &mut i32
}

for item in col {            // Calls col.into_iter()
    process(item);           // i32, consumes col
}

Additional Iterator Methods

impl<T> Collection<T> {
    // Domain-specific iterators follow similar patterns
    
    /// Iterates over keys (for map-like structures).
    fn keys(&self) -> impl Iterator<Item = &K> { ... }
    
    /// Iterates over values.
    fn values(&self) -> impl Iterator<Item = &V> { ... }
    
    /// Iterates over mutable values.
    fn values_mut(&mut self) -> impl Iterator<Item = &mut V> { ... }
    
    /// Drains elements, leaving container empty.
    fn drain(&mut self) -> impl Iterator<Item = T> { ... }
}

See Also