0

I have a Grid struct like this:

pub struct Grid<Item : Copy> {
    raw : Vec<Vec<Item>>
}

I'm trying to rewrite different kinds of iterators over it (mostly as an exercise, so I want to do this even if there are "better" ways of solving the specific problem presented here).

Iterating over rows was easy; the raw field is just a vector of rows, so I can yield a reference to each subsequent row each time.

But I'm having difficulty with iterating over columns. I tried to construct a new Vec for each call to next(), but the reference doesn't live long enough - which makes sense. The code below is an attempt to store the reference to the temporary vec in the iterator struct, hoping to inherit the lifetime. But that doesn't work either:

pub struct ColIter<'a, T>
    where T : 'a + Copy + Debug + Display + FromStr
{
    grid : &'a Grid<T>,
    index : usize,
    col_temp : Vec<T>,
}

impl <'a,T> ColIter<'a,T>
    where T : 'a + Copy + Debug + Display + FromStr
{
    fn new( grid : &'a Grid<T> ) -> ColIter<'a,T> {
        ColIter {
            grid : grid,
            index : 0,
            col_temp : Vec::with_capacity(grid.width()),
        }
    }
}

impl <'a,T> Iterator for ColIter<'a,T>
    where T : Copy + Debug + Display + FromStr
{
    type Item = &'a Vec<T>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.index < self.grid.height() {
            for row in 0..self.grid.width() {
                self.col_temp[row] = self.grid.raw[row][self.index];
            }
            self.index += 1;
            Some( & self.col_temp )    // <-- ERROR HERE
        }
        else {
            None
        }
    }
}

Which gives the error:

src/grid.rs:253:19: 253:34 error: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
src/grid.rs:253             Some( & self.col_temp )
                                  ^~~~~~~~~~~~~~~
src/grid.rs:247:5: 258:6 help: consider using an explicit lifetime parameter as shown: fn next(&'a mut self) -> Option<Self::Item>

The "help" line doesn't help, because the suggestion is incompatible with the trait.

Peter Hall
  • 53,120
  • 14
  • 139
  • 204
  • @Shepmaster But then I get this error: expected `&collections::vec::Vec`, found `collections::vec::Vec` – Peter Hall Dec 03 '15 at 01:13
  • 1
    Right — return the entire `Vec` (`type Item = Vec`). – Shepmaster Dec 03 '15 at 01:16
  • Ah, I see. That works. I think my problem was that I wrote the rows iterator first (because it was easier) and the obvious way to do that was to borrow references to the rows that I already had, so then I tried to use references too for the columns for consistency. I should be able to go back and make the row iterator work like this too. – Peter Hall Dec 03 '15 at 01:25

0 Answers0