rustiterator

In Rust, how to write a generic function that accepts iterator of a reference to a trait?


I want to implement a function that accepts an iterator to a trait.

trait A
{
    fn f(&self);
}

fn foo<It>(it: It)
where
    It: Iterator,
    It::Item: A
{
    it.for_each(|x| x.f());
}

This works if I move an object into the function:

let aa = vec![...]; // it has some objects that implement A
foo(aa.into_iter());

However, if I don't want to move out my container, then it won't work, because the compiler complains that &Something doesn't implement A.

foo(aa.iter());

I could just accept a slice.

fn foo(aa: &[impl A]) { ... }

But then it would only work if I pass it a simple container, but not if I want something more complicated like this:

foo(bars.iter().map(|bar| bar.a));

Solution

  • Introduce another generic type parameter T so that the constraints that the iterator Item is &T and that T implements A can be defined separately:

    fn foo<'a, T: 'a, It>(it: It)
    where
        It: Iterator<Item = &'a T>,
        T: A,
    {
        it.for_each(|x| x.f());
    }