I have a struct that directly wraps an iterator. I want to implement FromIterator
for it but I'm getting an error with associated types/generics.
Here is a condensed example:
Could someone explain why A
cannot be T::IntoIter
? Thanks
I have a struct that directly wraps an iterator. I want to implement FromIterator
for it but I'm getting an error with associated types/generics.
Here is a condensed example:
Could someone explain why A
cannot be T::IntoIter
? Thanks
T::IntoIter
could be A
, but it could also be anything else. If you make it a normal method, you can add the bound and it works
impl<A> Wrapper<A>
where
A: Iterator<Item = usize>,
{
fn from_iter<T: IntoIterator<Item = usize, IntoIter = A>>(iter: T) -> Self {
Wrapper {
inner: iter.into_iter(),
}
}
}
You can't add the right bound for the trait method though. FromIterator
is intended to consume the iterator it's used on, not just store it in the type. That's why the trait signature doesn't have a way to add a bound like the one you need. It's just not what the trait was designed for.
As an example, this snippet uses FromIterator
(indirectly via collect
) to create a Vec<String>
from the array of numbers. The iterator doesn't exist anymore after collect
is finished. It was consumed by the FromIterator
impl to build up the Vec<String>
let strings: Vec<String> = [1, 2, 3, 4].iter().map(|x| x.to_string()).collect::<Vec<_>>();
If you're trying to create an iterator adapter like map
, that's generally done via an extension trait like Itertools
which allows you to call your extension method right on the iterator you're going to wrap as long as the extension trait is in scope.