fn is a function pointer type (concrete, no captures, zero-cost). Fn is a trait (abstraction, captures, generic). fn = type, Fn = trait.
fn — concrete function pointer:
fn(Args) -> Output.1fn square(x: f64) -> f64 { x * x }23let op: fn(f64) -> f64 = square;4println!("{}", op(4.0)); // 16.056fn apply_all(fns: &[fn(f64) -> f64], x: f64) -> Vec<f64> {7 fns.iter().map(|f| f(x)).collect()8}910let results = apply_all(&[f64::sqrt, f64::abs, square], 9.0);11println!("{:?}", results); // [3.0, 9.0, 81.0]
Fn — closure trait:
1let name = "Rust";2let greet = || format!("Hello, {}!", name); // Fn3println!("{}", greet()); // Hello, Rust!45fn bench<F: Fn(u32) -> u32>(name: &str, f: F, n: u32) {6 let start = std::time::Instant::now();7 for _ in 0..n { f(42); }8 println!("{}: {:?}", name, start.elapsed());9}1011bench("square", |x| x * x, 1000);12bench("double", |x| x * 2, 1000);
When to use fn:
When to use Fn/FnMut/FnOnce:
Common mistakes: