fn is a function pointer type — concrete, no captures, zero-cost. Fn is a trait — abstraction, captures, generic. fn is a type; Fn is a trait.
fn — function pointer:
fn(Args) -> Output.1fn wrap(x: i32) -> String {2 format!("[{}]", x)3}45let formatter: fn(i32) -> String = wrap;6println!("{}", formatter(42)); // [42]78// Function table9let formatters: &[fn(i32) -> String] = &[10 |x| format!("hex: {:x}", x),11 |x| format!("oct: {:o}", x),12 wrap,13];
Fn — closure trait:
1let prefix = "LOG:";2let log_msg = |msg| format!("{} {}", prefix, msg); // Fn3println!("{}", log_msg("started")); // LOG: started45fn execute<F: FnOnce() -> String>(f: F) -> String {6 f() // FnOnce: can only be called once7}89let name = String::from("Rust");10let result = execute(move || format!("Hello, {}!", name));11println!("{}", result); // Hello, Rust!
When to use fn:
When to use Fn/FnMut/FnOnce:
Common mistakes: