IntoIterator

The Iterator trait tells you how to iterate once you have created an iterator. The related trait IntoIterator defines how to create an iterator for a type. It is used automatically by the for loop.

1. ```
   struct Grid {
   ```
2. ```
       x_coords: Vec<u32>,
   ```
3. ```
       y_coords: Vec<u32>,
   ```
4. ```
   }
   ```

6. ```
   impl IntoIterator for Grid {
   ```
7. ```
       type Item = (u32, u32);
   ```
8. ```
       type IntoIter = GridIter;
   ```
9. ```
       fn into_iter(self) -> GridIter {
   ```
10. ```
            GridIter { grid: self, i: 0, j: 0 }
    ```
11. ```
        }
    ```
12. ```
    }
    ```

14. ```
    struct GridIter {
    ```
15. ```
        grid: Grid,
    ```
16. ```
        i: usize,
    ```
17. ```
        j: usize,
    ```
18. ```
    }
    ```

20. ```
    impl Iterator for GridIter {
    ```
21. ```
        type Item = (u32, u32);
    ```

23. ```
        fn next(&mut self) -> Option<(u32, u32)> {
    ```
24. ```
            if self.i >= self.grid.x_coords.len() {
    ```
25. ```
                self.i = 0;
    ```
26. ```
                self.j += 1;
    ```
27. ```
                if self.j >= self.grid.y_coords.len() {
    ```
28. ```
                    return None;
    ```
29. ```
                }
    ```
30. ```
            }
    ```
31. ```
            let res = Some((self.grid.x_coords[self.i], self.grid.y_coords[self.j]));
    ```
32. ```
            self.i += 1;
    ```
33. ```
            res
    ```
34. ```
        }
    ```
35. ```
    }
    ```

37. ```
    fn main() {
    ```
38. ```
        let grid = Grid { x_coords: vec![3, 5, 7, 9], y_coords: vec![10, 20, 30, 40] };
    ```
39. ```
        for (x, y) in grid {
    ```
40. ```
            println!("point = {x}, {y}");
    ```
41. ```
        }
    ```
42. ```
    }
    ```

This slide should take about 5 minutes.

Click through to the docs for IntoIterator. Every implementation of IntoIterator must declare two types:

  • Item: the type to iterate over, such as i8,
  • IntoIter: the Iterator type returned by the into_iter method.

Note that IntoIter and Item are linked: the iterator must have the same Item type, which means that it returns Option<Item>

The example iterates over all combinations of x and y coordinates.

Try iterating over the grid twice in main. Why does this fail? Note that IntoIterator::into_iter takes ownership of self.

Fix this issue by implementing IntoIterator for &Grid and storing a reference to the Grid in GridIter.

The same problem can occur for standard library types: for e in some_vector will take ownership of some_vector and iterate over owned elements from that vector. Use for e in &some_vector instead, to iterate over references to elements of some_vector.