As of Rust 1.26, you can use impl trait
:
fn make_adder(a: i32) -> impl Fn(i32) -> i32 {
move |b| a + b
}
fn main() {
println!("{}", make_adder(1)(2));
}
This allows returning an unboxed closure even though it is impossible to specify the exact type of the closure.
This will not help you if any of these are true:
-
You are targeting Rust before this version
-
You have any kind of conditional in your function:
fn make_adder(a: i32) -> impl Fn(i32) -> i32 { if a > 0 { move |b| a + b } else { move |b| a - b } }
Here, there isn’t a single return type; each closure has a unique, un-namable type.
-
You need to be able to name the returned type for any reason:
struct Example<F>(F); fn make_it() -> Example<impl Fn()> { Example(|| println!("Hello")) } fn main() { let unnamed_type_ok = make_it(); let named_type_bad: /* No valid type here */ = make_it(); }
You cannot (yet) use
impl SomeTrait
as a variable type.
In these cases, you need to use indirection. The common solution is a trait object, as described in the other answer.