How to loop over boxed iterator?

4.5k Views Asked by At

Note: This question is obsolete since Rust 1.0. The Iterator trait now has an associated type, Item, instead of a type parameter and a blanket Iterator implementation was added for Box<Iterator>.

I want to define a trait method that returns an iterator. I want to avoid specifying what the actual return type is, so until we have unboxed abstract return types, I'm using trait objects. This means the method returns Box<Iterator<A>>. But I'm not sure how to use a boxed trait object. I can't iterate over an object of type Box<Iterator<A>>:

fn main() {
    let xs = vec![0u, 1, 2, 3];
    let boxed_iter = box xs.iter() as Box<Iterator<&uint>>;
    for x in boxed_iter {}
}

This errors with "for" loop expression does not implement the "Iterator" trait.

So my question is: How can I iterate over Box<Iterator<A>>. Or, more generally, how can I used boxed trait objects?

1

There are 1 best solutions below

3
On

The issue is that Box<Iterator<A>> does not itself implement the Iterator trait. (I'm not sure exactly why, perhaps someone else can chime in on that point.)

You could remedy this yourself with:

impl<A> Iterator<A> for Box<Iterator<A>> {
    fn next(&mut self) -> Option<A> { self.next() }
}

But since neither type nor trait are defined in your crate, this is not allowed. To work around this, you could define your own sub-trait of Iterator, implement Iterator<A> for all Box<MyIter<A>> and then implement MyIter<A> for all types I that satisfy Iterator<A>:

trait MyIter<A> : Iterator<A> {}
impl<A, I: Iterator<A>> MyIter<A> for I {}

// This is now allowed because `MyIter` is defined in this crate.
impl<A> Iterator<A> for Box<MyIter<A>> {
    fn next(&mut self) -> Option<A> { self.next() }
}

And you'd have to change your code to use as Box<MyIter<&uint>>:

fn main() {
    let xs = vec![0u, 1, 2, 3];
    let mut boxed_iter = box xs.iter() as Box<MyIter<&uint>>;
    for x in boxed_iter { println!("{}", x); }
}

(I added mutability to boxed_iter since it is required for iterators.)