I’m trying to implement an iterator for a 2D board. This Board is of the type [[Option<u8>; SIZE]; SIZE] and I created an iterator for traversing a square of given length.
struct SquareIterator<'a> {
board: &'a Board,
sqr_size: usize,
row: usize,
col: usize,
row_iter: usize,
col_iter: usize,
}
For convenience I figured I could implement the IntoIterator on Board to traverse the whole board aka a SquareIterator of sqr_size = SIZE and row=col=0.
So first tried this:
impl<'a> IntoIterator for Board<'a> {
type IntoIter = SquareIterator<'a>;
type Item = <SquareIterator<'a> as Iterator>::Item;
fn into_iter(self) -> Self::IntoIter { /*(...)*/ }
}
not surprisingly it doesn’t compile: error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied. Board indeed takes no lifetime arguments.
But I somehow want to tie the lifetime of SquareIterator to whatever lifetime a Board has. I have no idea how to achieve this.
>Solution :
You’re implementing IntoIterator for the wrong thing!
Since your SquareIterator takes a &Board you should implement for that instead:
impl<'a> IntoIterator for &'a Board {
type IntoIter = SquareIterator<'a>;
type Item = <SquareIterator<'a> as Iterator>::Item;
fn into_iter(self) -> Self::IntoIter { /*(...)*/ }
}
usually you’d add a iter or similarly named method to the inherent impl block of Board as well:
impl Board {
fn iter(&self) -> SquareIterator<'_> {
self.into_iter()
}
}