Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
        }
    }
}
like image 818
Spiderpig Avatar asked Oct 30 '22 20:10

Spiderpig


1 Answers

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

like image 70
oli_obk Avatar answered Nov 10 '22 11:11

oli_obk