Closure as the function parameter
(Jin Qing's Column, Mar., 2022)
It is best to let the function take a closure trait as the parameter instead of a function pointer.
fn foo(f: fn()) {
f()
}
fn main() {
foo(|| println!("hello"));
let a = 123;
foo(move || println!("{}", a))
}
compiles error:
error[E0308]: mismatched types
--> src/main.rs:9:9
|
9 | foo(move || println!("{}", a))
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn pointer, found closure
|
= note: expected fn pointer `fn()`
found closure `[closure@src/main.rs:9:9: 9:34]`
note: closures can only be coerced to `fn` types if they do not capture any variables
--> src/main.rs:9:32
|
9 | foo(move || println!("{}", a))
| ^ `a` captured here
For more information about this error, try `rustc --explain E0308`.
https://doc.rust-lang.org/book/ch19-05-advanced-functions-and-closures.html
Function pointers implement all three of the closure traits (Fn, FnMut, and FnOnce), so you can always pass a function pointer as an argument for a function that expects a closure. It’s best to write functions using a generic type and one of the closure traits so your functions can accept either functions or closures.