[Rust Guide] 13.2. Closure Type Inference and Annotations Rust closures, unlike functions, do not require explicit type annotations for parameters or return values because they are typically used in narrow contexts where the compiler can infer types. The compiler infers a single concrete type for each parameter and return value based on usage, and attempting to use a closure with different types results in a compile-time error. During its design, Rust drew inspiration from many languages, and functional programming had a particularly strong influence on Rust. Functional programming often includes passing functions as values to parameters, returning them from other functions, assigning them to variables for later execution, and so on. In this chapter, we will discuss some Rust features that are similar to what many languages call functional features: If you find this helpful, please like, bookmark, and follow. To keep learning along, follow this series. Unlike functions defined with fn , closures do not require explicit type annotations for parameters or return values. Functions must be explicit because they are part of a public interface exposed to users, and a clearly defined interface helps everyone agree on the parameter and return types. Closures are not used as exposed interfaces. They are usually stored in variables, they do not need names when used, and they are not exposed to users of our codebase. Therefore, closures do not require explicit type annotations for parameters and return values. Closures are also usually short and work only in a narrow context, so the compiler can often infer the types. Of course, you can still write the annotations manually if you want to. Take a look at an example: This is the version using a function definition: php fn simulated expensive calculation intensity: u32 - u32 { println "calculating slowly..." ; thread::sleep Duration::from secs 2 ; intensity } This is the version using a closure: php let expensive closure = |num:u32| - u32 { println "calculating slowly..." ; thread::sleep Duration::from secs 2 ; num }; Explicit annotations are used here because there is no surrounding context for Rust to infer the types. If there is context, then they are not needed: js fn generate workout intensity: u32, random number: u32 { let expensive closure = |num| { println "calculating slowly..." ; thread::sleep Duration::from secs 2 ; num }; if intensity < 25 { println "Today, do {} pushups ", expensive closure intensity ; println "Next, do {} situps ", expensive closure intensity ; } else { if random number == 3 { println "Take a break today Remember to stay hydrated " ; } else { println "Today, run for {} minutes ", expensive closure intensity ; } } } The parameter num does not need an explicit type annotation because the argument passed in the later call is intensity , whose type is u32 , so Rust infers that num is also u32 . Here are four examples: php fn add one v1 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 ; {} . Because it contains only one expression, the braces can be omitted.A closure’s definition will ultimately infer only one specific concrete type for its parameters and return value. Take a look at an example: js let example closure = |x| x; let s = example closure String::from "hello" ; let n = example closure 5 ; Output: bash $ cargo run Compiling closure-example v0.1.0 file:///projects/closure-example error E0308 : mismatched types -- src/main.rs:5:29 | 5 | let n = example closure 5 ; | --------------- ^- help: try using a conversion method: .to string | | | | | expected String , found integer | arguments to this function are incorrect | note: expected because the closure was earlier called with an argument of type String -- src/main.rs:4:29 | 4 | let s = example closure String::from "hello" ; | --------------- ^^^^^^^^^^^^^^^^^^^^^ expected because this argument is of type String | | | in this closure call note: closure parameter defined here -- src/main.rs:2:28 | 2 | let example closure = |x| x; | ^ For more information about this error, try rustc --explain E0308 . error: could not compile closure-example bin "closure-example" due to 1 previous error When the compiler sees the first call to the closure, it determines that both the input and output values are String , so it locks in String as the parameter and return type for this closure. That is why a later call with an integer causes an error.