Is there a way to use a traits associated type as a generic type?

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 :slight_smile:

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

Playground

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.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.