I'm reading the book rust authoritative guide. When I see the closure chapter, why can't the following code be compiled
fn main() {
let x_closure = |x| x + 2;
}
I'm reading the book rust authoritative guide. When I see the closure chapter, why can't the following code be compiled
fn main() {
let x_closure = |x| x + 2;
}
The book says that closures can be inferred automatically without defining data types
What is the type of the closure's x
parameter? Without an annotation (e.g. |x: u32| ...
) it's ambiguous, because there are a large number of types which would make the expression, x+2
, valid.
This is an error message
type annotations needed
consider giving this closure parameter a typerustc(E0282)
main.rs(2, 22): consider giving this closure parameter a type
fn add_one (x: u32) -> u32 { x +1 }
let add_one_v2 = |x: u32| -> u32 { x+1 };
let add_one_v3 = |x| { x+1 };
let add_one_v4 = |x| x+1;
For rustc to correctly infer the type of the closure's argument, the closure must actually be used somewhere. For example, this program compiles, since the closure is inferred to be a Fn(i32) -> i32
:
fn main() {
let x_closure = |x| x + 2;
println!("{}", x_closure(3));
}
And this program compiles, since the closure is inferred to be a Fn(&i32) -> i32
:
fn main() {
let x_closure = |x| x + 2;
println!("{}", x_closure(&3));
}
But this does not compile, since the closure is inferred to be a Fn(i32) -> i32
and cannot accept an &i32
:
fn main() {
let x_closure = |x| x + 2;
println!("{}", x_closure(3));
println!("{}", x_closure(&3));
// mismatched types: expected integer, found `&{integer}`
}
So there's really three sources from which closure parameters' types can be determined:
In your example, none of the three sources specify the type of x
. The compiler knows that the type of x
must implement Add<{integer}>
for a certain {integer}
type, but it cannot work backward to determine the exact type. This is why it gives an error.
thanks