Situation:
I have a situation where I would like to call some method defined on the Iterator trait on a function parameter. The function that I would like to call it is taking a parameter of a type which is a trait called VecLike. The function is called get_all_matching_rules.
get_all_matching_rules can receive either a Vec or another similar home made type which also implements Iterator. Of course both of these implement VecLike. I was thinking of adding a function on VecLike to have it return an Iterator so that I could use it in get_all_matching_rules.
If my parameter is named: matching_rules I could then do matching_rules.iter().filter(.
Question:
How do I return a non consuming iterator from a Vec?
I'd like to be able to return a non consuming iterator on a Vec<T> of type Iterator<T>. I am not looking to iterate the items by calling .iter().
If I have (where self is a Vec):
fn iter<'a>(&'a self) -> Iterator<T> {
self.iter()
}
I get the following error:
error: mismatched types: expected `core::iter::Iterator<T>+'a`, found `core::slice::Items<'_,T>` (expected trait core::iter::Iterator, found struct core::slice::Items)
I would like to return the Iterator<t>. If there is a better way to go at this rather than returning an Iterator, I'm all ears.
.iter() on [T], which Vec<T> automatically dereferences to, takes self by reference and produces a type implementing Iterator<&T>. Note that the return type is not Iterator<&T>; Iterator is a trait which is implemented by concrete types, and the concrete type Items<T> is the return type in that case, not Iterator<&T>. There is not currently any syntax for specifying a return type merely as a trait that is implemented by it, though the syntax impl Iterator<&T> has been suggested.
Now you wish something implementing Iterator<T> rather than Iterator<&T>. Under Rust’s memory model where each object is owned by exactly one thing, this is not possible with the same objects; there must be some constraint to allow you to get a new T from the &T. There are two readily provided solutions for this:
The Copy trait, for types that can just be copied bitwise. Given a variable of a type implementing Iterator<&T> where T is Copy, this can be written .map(|&x| x) or .map(|x| *x) (the two are equivalent).
The Clone trait, for any types where the operation can be caused to make sense, regardless of Copy bounds. Given a variable of a type implementing Iterator<&T> where T is Clone, this can be written .map(|x| x.clone()).
Thus, given a vector v, v.iter().map(|x| x.clone()). Generically, something like this:
fn iter<T: Clone>(slice: &[T]) -> Map<&T, T, Items<T>> {
slice.iter().map(|x| x.clone())
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With