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())
}
I'm not sure what you're asking here.
.iter()
creates an iterator (Items
) which does not move the Vec
(You'll get an Iterator over &T
).
Filter
(and most other iterator adapters) are lazy. Perhaps you should chain()
the two iterators before filtering them?
Otherwise, if you don't want the Filter
to be consumed, clone it.