How to model a trait for a container with iterator

I want to create a trait for some sort of container object that allows iterating over its items in some specific way:

trait Container {
    type Item;
    fn iter_items() -> SomeIteratorType;
}

Now, my Poblem is: How do I specify the iterator type? since in general it should be possible to implement "interesting" ways of iterating, how should allow a custom iterator type. So my Idea is this:

trait Container {
    type Item;
    type ItemIterator: Iterator<Item=Item>;
    fn iter_items() -> SomeIteratorType;
}

Now, the lifetime of the Iterator should not be longer than the lifetime of the Container itself, because the iterator might reference the Container.

Now my questions:

  1. Is it a good Idea to make the Iterator type a type Parameter, or should I do that some other way?
  2. How do I have to insert lifetime paramters, to ensure the Container does not longer life than the Iterator returned by "iter_itmes"?

If you're giving iter_items a self argument (which seems more reasonable than no argument at all, given your description of what you're trying to achieve; don't forget that Rust does not have implicit this pointers) it seems like you're slowly re-inventing the IntoIterator trait here; in case you weren't aware of that one, take a look.

If you were thinking about a &self method instead (which is when lifetimes to come into play) then the approach taken in the standard library is to simply implement impl<'a> IntoIterator for &'a Collection i. e. implement the trait for the reference type. This way you also get access to a lifetime 'a you can use in the iterator type and the item type.

5 Likes

With GATs, this would be something like

pub trait Iterable {
    type Item<'a> where Self: 'a;
    type Iter<'a>: Iterator<Item=<Self as Iterable>::Item<'a>> where Self: 'a;
    fn iter(&self) -> <Self as Iterable>::Iter<'_>;
}

But as @steffahn said, instead/for now we have impl<'a> IntoIterator for &'a MySelf (and a convention of having an inherent iter method).

2 Likes