从闭包中返回闭包作为函数的返回值

时间:2019-05-18 18:21:02

标签: rust closures traits

我正试图习惯impl Fn,但我不理解此代码的错误:

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);
}

错误是:

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. 为什么第一个impl Fn不允许使用第二个{}?
  2. 如何在不使用堆的情况下(通过Box等来完成此操作?

1 个答案:

答案 0 :(得分:3)

如果您仔细阅读该消息,它将确切说明问题所在:

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

目前,您只能使用impl Trait

  • 作为函数的返回类型:fnimpl块之外使用。
  • 作为固有方法的返回类型:fn块中使用的impl Type

就是这样。

因此,您无法形成特征Fn() -> impl X

我会指出,这是暂时的限制,因为正在进行工作以扩展可以使用impl X的地方,并且需要相关的类型和特征方法。

  

为什么第一个impl Fn被允许,但第二个不允许?

第一个impl Fn是函数的返回类型(y),因此可以使用。第二个是trait方法的返回类型,所以不是。

  

不使用堆怎么办?

您可以从第一个Fn中返回一个具体实例。

例如,如果您不需要状态,则可以返回fn(bool) -> bool

否则,您将需要手动创建一个封装所述状态的结构,以便能够命名类型,而不是依赖于闭包。