Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Code shared from the Rust Playground
// Takes a function pointer from i32 to i32
fn takes_a_fp(f: fn(i32) -> i32, value: i32) -> i32 {
f(value)
}
// Takes a closure with the trait bound Fn(i32) -> i32
fn takes_a_closure<T: Fn(i32) -> i32>(f: T, value: i32) -> i32 {
f(value)
}
// Takes a closure with the trait bound Fn(i32) -> i32 using 1.26 impl syntax
fn takes_a_closure_impl(f: impl Fn(i32) -> i32, value: i32) -> i32 {
f(value)
}
// Takes an optional function pointer from i32 to i32
fn takes_an_opt_fp(f: Option<fn(i32) -> i32>, value: i32) -> Option<i32> {
if let Some(f) = f {
Some(f(value))
} else {
None
}
}
// Takes an optional closure with the trait bound Fn(i32) -> i32
fn takes_an_opt_closure<T: Fn(i32) -> i32>(f: Option<T>, value: i32) -> Option<i32> {
if let Some(f) = f {
Some(f(value))
} else {
None
}
}
// Takes an optional closure with the trait bound Fn(i32) -> i32 using 1.26 impl syntax
fn takes_an_opt_closure_impl(f: Option<impl Fn(i32) -> i32>, value: i32) -> Option<i32> {
if let Some(f) = f {
Some(f(value))
} else {
None
}
}
// Function from i32 -> i32
fn id(x: i32) -> i32 {
x
}
fn main() {
// Closure from i32 -> i32
let closure = |x: i32| x;
println!("takes_a_fp(closure, 42): {}", takes_a_fp(closure, 42));
println!("takes_a_fp(fn, 42): {}", takes_a_fp(id, 42));
println!();
println!("takes_a_closure(closure, 42): {}", takes_a_closure(closure, 42));
println!("takes_a_closure(fn, 42): {}", takes_a_closure(id, 42));
println!();
println!("takes_a_closure_impl(closure, 42): {}", takes_a_closure_impl(closure, 42));
println!("takes_a_closure_impl(fn, 42): {}", takes_a_closure_impl(id, 42));
println!();
println!("takes_an_opt_fp(closure, 42): {:?}", takes_an_opt_fp(Some(closure), 42));
println!("takes_an_opt_fp(fn, 42): {:?}", takes_an_opt_fp(Some(id), 42));
// The type of `f` is unambiguous, therefore Rust can infer the correct type of Option<f> for None
println!("takes_an_opt_fp(None, 42): {:?}", takes_an_opt_fp(None, 42));
println!();
println!("takes_an_opt_closure(closure, 42): {:?}", takes_an_opt_closure(Some(closure), 42));
println!("takes_an_opt_closure(fn, 42): {:?}", takes_an_opt_closure(Some(id), 42));
println!("takes_an_opt_closure(None, 42): {:?}", takes_an_opt_closure(None::<fn(_) -> i32>, 42));
println!();
println!("takes_an_opt_closure_impl(closure, 42): {:?}", takes_an_opt_closure_impl(Some(closure), 42));
println!("takes_an_opt_closure_impl(fn, 42): {:?}", takes_an_opt_closure_impl(Some(id), 42));
// The type of `f` is unambiguous, therefore Rust can infer the correct type of Option<f> for None
println!("takes_an_opt_closure_impl(None, 42): {:?}", takes_an_opt_closure_impl(None::<fn(_) -> i32>, 42));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment