fn is a function pointer type — concrete, no captures, zero-cost. Fn is a trait — abstraction, captures, generic. fn = type, Fn = trait.
fn — function pointer:
fn(Args) -> Output.1fn to_uppercase(s: &str) -> String {2 s.to_uppercase()3}45let transform: fn(&str) -> String = to_uppercase;6println!("{}", transform("hello")); // HELLO78fn apply_transforms(text: &str, transforms: &[fn(&str) -> String]) -> String {9 transforms.iter().fold(text.to_string(), |acc, t| t(&acc))10}
Fn — closure trait:
1let offset = 10;2let add_offset = |x: i32| x + offset; // Fn3println!("{}", add_offset(5)); // 1545fn pipeline<F: Fn(i32) -> i32, G: Fn(i32) -> i32>(6 value: i32,7 f: F,8 g: G,9) -> i32 {10 g(f(value))11}1213let result = pipeline(5, |x| x * 2, |x| x + 1);14println!("{}", result); // 11
When to use fn:
When to use Fn/FnMut/FnOnce:
Common mistakes: