In cases like this, it’s very useful to force the compiler to tell you the type of the variable. Let’s trigger a type error by assigning the closure argument to an incompatible type:
array_iter.filter(|x| { let _: () = x; x == 2 });
This fails with:
error[E0308]: mismatched types
--> src/lib.rs:4:41
|
4 | array_iter.filter(|x| { let _: () = x; x == 2 });
| -- ^ expected `()`, found `&&{integer}`
| |
| expected due to this
Now we know the type of x
is a &&{integer}
– a reference to a reference to some kind of integer. We can then match against that instead:
fn hooray() {
let array = [1, 4, 3, 2, 2];
let array_iter = array.into_iter();
array_iter.filter(|&&x| x == 2);
}
The question now becomes “why is it a reference to a reference”? The short version is that the iterator of an array returns references (see the type Item = &'a T
part). In addition, Iterator::filter
passes a reference to the closure to prevent moving and subsequently losing non-Copy
types.
In Rust 1.51, you can use array::IntoIter
to get a by-value iterator:
fn hooray() {
let array = [1, 4, 3, 2, 2];
let array_iter = std::array::IntoIter::new(array);
array_iter.filter(|&x| x == 2);
}