Returning a closure from a function

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:

  1. You are targeting Rust before this version

  2. 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.

  3. 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.

Leave a Comment