Rust libstd has one implementation of this, the IntoIterator trait.
/// Conversion into an `Iterator` pub trait IntoIterator { /// The type of the elements being iterated type Item; /// A container for iterating over elements of type `Item` type IntoIter: Iterator<Item=Self::Item>; /// Consumes `Self` and returns an iterator over it fn into_iter(self) -> Self::IntoIter; }
This trait has this specific formula ( self ) in order to be able to express the semantics of “into an iterator” and “borrow an iterator”.
Demonstrated by HashMap IntoIterator implementations. (They use the iterator hashmap structs Iter and IntoIter .) Interestingly, the trait is implemented for type &HashMap<K, V, S> to express "borrow iterator".
impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S> where K: Eq + Hash, S: HashState { type Item = (&'a K, &'a V); type IntoIter = Iter<'a, K, V>; fn into_iter(self) -> Iter<'a, K, V> { self.iter() } } impl<K, V, S> IntoIterator for HashMap<K, V, S> where K: Eq + Hash, S: HashState { type Item = (K, V); type IntoIter = IntoIter<K, V>; /// Creates a consuming iterator, that is, one that moves each key-value /// pair out of the map in arbitrary order. The map cannot be used after /// calling this. fn into_iter(self) -> IntoIter<K, V> { /* ... */ } }
bluss
source share