I wrote a function to iterate over neighbors of cells in a 2d grid:
pub fn neighbours(
(width, height): (usize, usize),
(x, y): (usize, usize),
) -> impl Iterator<Item = (usize, usize)> {
[(-1, 0), (1, 0), (0, -1), (0, 1)]
.iter()
.map(move |(dx, dy)| (x as i64 + dx, y as i64 + dy))
.filter(move |&(nx, ny)| 0 <= ny && ny < height as i64 && 0 <= nx && nx < width as i64)
.map(|(nx, ny)| (nx as usize, ny as usize))
}
Note that it returns an impl Iterator<Item = (usize, usize)>.
If I understand correctly, returning an impl would result in slower code, calling function pointers instead of compiling things down to simple loops. Right?
So wanting to specify a more exact type, I replaced the type with () to see what type the compiler infers, and it infers
std::iter::Map<std::iter::Filter<std::iter::Map<std::slice::Iter<'l, (i64, i64)>, _>, _>, _>
Where the _s stand for closures which I don't know how to specify their types.
I tried to extract the closures to structs with Fn traits but couldn't make that work and also IIUC implementing Fn traits is an unstable feature and I shouldn't use it"