简体   繁体   中英

Returning closure from a closure as return value for function

I'm trying to get used to impl Fn , but I don't understand the error for this code:

fn y(state: bool) -> impl Fn() -> impl Fn(bool) -> bool {
    move || {
        println!("state, {}", state);
        |x: bool| {
            println!("state, {}", state);
            !x
        }
    }
}

fn main() {
    y(true)()(true);
}

The error is:

error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
 --> src/main.rs:1:35
  |
1 | fn y(state: bool) -> impl Fn() -> impl Fn(bool) -> bool {
  |                                   ^^^^^^^^^^^^^^^^^^^^^
  1. Why is it allowed for the first impl Fn , but not allowed for the second?
  2. How this can be done without using the heap (via Box , etc.)?

If you read the message closer, it explains exactly what the issue is:

 `impl Trait` not allowed outside of function and inherent method return types 

At the moment, you can only use impl Trait :

  • As the return type of a function: fn used outside of an impl block.
  • As the return type of an inherent method: fn used in an impl Type block.

And that's it.

Therefore, you cannot form a trait Fn() -> impl X .

I would note that this is, hopefully, a temporary limitation as work is ongoing to extend the places where impl X can be used, and associated types and trait methods are desired.

Why is it allowed for the first impl Fn , but not allowed for the second?

The first impl Fn is the return type of a function ( y ) so it is allowed. The second is the return type of a trait method so it is not.

How this can be done without using the heap?

You could return a concrete instance out of the first Fn .

For example, if you do not need state, you could return a fn(bool) -> bool instead.

Otherwise, you would need to manually create a struct which encapsulates said state so as to be able to name the type, instead of relying on a closure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM