I was reading the chapter on higher order functions of Rust by Example. Where they present the following canonical example:
fn is_odd(n: u32) -> bool {
n % 2 == 1
}
fn main() {
let upper = 1000;
println!("imperative style: {}", acc);
let sum_of_squared_odd_numbers: u32 =
(0..).map(|n| n * n) // All natural numbers squared
.take_while(|&n_squared| n_squared < upper) // Below upper limit
.filter(|&n_squared| is_odd(n_squared)) // That are odd
.fold(0, |acc, n_squared| acc + n_squared); // Sum them
}
Simple enough. But I realized that I don't understand the type of parameter n_squared
. Both take_while
and filter
accept a function that takes a parameter by reference. That makes sense to me, you want to borrow instead of consuming the values in the map.
However, if n_squared
is a reference, why don't I have to dereference it before comparing its value to limit or equally surprising; why can I pass it directly to is_odd()
without dereferencing?
I.e. why isn't it?
|&n_squared| *n_squared < upper
When I try that the compiler gives the following error:
error[E0614]: type `{integer}` cannot be dereferenced
--> src\higherorder.rs:13:34
|
13 | .take_while(|&n_squared| *n_squared <= upper)
|
Indicating that n_squared
is an i32
and not &i32
. Looks like some sort pattern matching/destructuring is happening here, but I was unable to find the relevant documentation.
|n_squared|
, you'll get the expected error and using*n_squared
in the body will fix it. See reddit.com/r/rust/comments/16b9wh/… – Alexey Romanov