Spiderpig
Spiderpig

Reputation: 85

Lifetime issue when implementing Iterator

I was implementing the Iterator trait for several structs and encountered some problems. Why is implementing Iterator for Rows shows error? Here is a link: link to playground

Basically why this doesn't work?

struct Stripe<'a> {
    cells: &'a [u32],
}

struct Rows<'a> {
    foo: &'a Foo,
    vec: Vec<u32>,
    first: bool,
}

impl<'a> std::iter::Iterator for Rows<'a> {
    type Item = Stripe<'a>;
    fn next(&mut self) -> Option<Stripe<'a>> {
        if self.first {
            self.first = false;
            Some(
                Stripe {
                    cells: &self.vec[0..1],
                }
            )
        } else {
            None
        }
    }
}

Upvotes: 6

Views: 543

Answers (1)

oli_obk
oli_obk

Reputation: 31183

The lifetime 'a in the Row type refers only to one field of the type. The references you are returning have nothing to do with that lifetime. The Iterator trait does not allow you to return lifetimes into the iterator-object itself. That would require adding a new lifetime to the next function.

I suggest you create a RowsIterator type with a reference to your Rows object and handle the iterator-specific stuff in there:

struct Stripe<'a> {
    cells: &'a [u32],
}

struct Rows {
    vec: Vec<u32>,
}

struct RowsIter<'a> {
    rows: &'a Rows,
    first: bool,
}

impl<'a> std::iter::Iterator for RowsIter<'a> {
    type Item = Stripe<'a>;
    fn next(&mut self) -> Option<Stripe<'a>> {
        if self.first {
            self.first = false;
            Some(
                Stripe {
                    cells: &self.rows.vec[0..1],
                }
            )
        } else {
            None
        }
    }
}

Full example in the playground

Upvotes: 3

Related Questions