214. slice::windows — Compare Consecutive Elements Without the Index Math
The classic “look at each element and the next one” loop is a panic waiting to happen: 0..v.len() - 1 underflows the moment the slice is empty. windows hands you every consecutive pair safely, no arithmetic required.
Whenever you need to look at neighbouring elements — deltas between samples, “is each one bigger than the last”, spotting a transition — the reflex is to index by hand:
| |
This works until v is empty. v.len() is 0, v.len() - 1 underflows on usize, and the loop panics before it even starts. You end up bolting on an if !v.is_empty() guard, and the v[i + 1] indexing still pays a bounds check every iteration.
slice::windows(n) gives you an iterator of overlapping sub-slices of length n. Ask for 2 and you get each consecutive pair, with no index juggling and no empty-slice trap:
| |
Because windows yields nothing when the slice is shorter than n, the empty and single-element cases just fall out for free — no special handling:
| |
It composes with the rest of the iterator toolbox, too. Checking that a slice is strictly increasing becomes one readable line:
| |
The window size isn’t limited to 2 — pass 3 for sliding triples (handy for smoothing or peak detection), and each window is a real slice you can index, sum, or pattern-match:
| |
One caveat: the windows overlap and share elements, so windows only hands out shared (&) references — you can’t mutate through them. When you want non-overlapping fixed-size groups instead, reach for chunks. But for anything that compares an element to its neighbours, windows replaces the fragile len() - 1 loop with code that can’t go out of bounds.