`for`-loops, patterns matching, and .windows(usize)

⚓ Rust    📅 2025-09-26    👤 surdeus    👁️ 7      

surdeus

Warning

This post was published 35 days ago. The information described in this article may have changed.

When I reach for .windows(), I always find that I want to use it like this:

let slice = ['l', 'O', 'R', 'e', 'm'];

for [a , b] in slice.windows(2) {
    if a.is_uppercase() && b.is_uppercase() {
        println!("Found consecutive capitals: {a}{b}");
    }
}

But this doesn't compile because:

error[E0005]: refutable pattern in `for` loop binding
 --> src/main.rs:4:9
  |
4 |     for [a , b] in slice.windows(2) {
  |         ^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _, _, ..]` not covered
  |
  = note: the matched value is of type `&[char]`

For more information about this error, try `rustc --explain E0005`.

I'm a bit confused by this error, since the docs for windows() specify that it's an iterator which always returns slices of length size. And, indeed, it will return nothing if slice is too short to give a single window.

I know this can be worked around using if let:

let slice = ['l', 'O', 'R', 'e', 'm'];

for window in slice.windows(2) {
    if let [a , b] = window && a.is_uppercase() && b.is_uppercase() {
            println!("Found consecutive capitals: {a}{b}");
        }
    }
}

But… why is the extra layer of pattern matching required? Isn't the for already assigning items from the slice into new scoped variables? Why isn't the pattern irrefutable in the for-of-windows case?

Anyway, if there's a better/more concise way to use .windows(), I'd love to hear it. Or maybe there's some language feature which will eventually make this easier to do?

3 posts - 3 participants

Read full topic

🏷️ Rust_feed