rust - 从函数返回闭包

标签 rust

注意:这个问题是在 Rust 的第一个稳定版本发布之前提出的。自那以后发生了很多变化,函数中使用的语法甚至不再有效。不过,Shepmaster 的回答非常好,让这个问题值得保留。


最终未装箱的封闭物已经落地,所以我正在对它们进行试验,看看您能做什么。

我有这个简单的功能:

fn make_adder(a: int, b: int) -> || -> int {
    || a + b
}

但是,我收到了一个缺少生命周期说明符 [E0106] 错误。我试图通过将返回类型更改为 ||: 'static -> int 来解决此问题,但随后出现另一个错误 cannot infer an appropriate lifetime due to conflicting requirements .

如果我没理解错的话,闭包是未装箱的,因此它拥有 ab。它需要一生,这对我来说似乎很奇怪。我该如何解决这个问题?

最佳答案

从 Rust 1.26 开始,您可以使用 impl trait :

fn make_adder(a: i32) -> impl Fn(i32) -> i32 {
    move |b| a + b
}

fn main() {
    println!("{}", make_adder(1)(2));
}

这允许返回一个未装箱 的闭包,即使不可能指定闭包的确切类型。

如果以下任何一项为真,这将不会帮助您:

  1. 您在此版本之前的目标是 Rust

  2. 您的函数中有任何类型的条件:

    fn make_adder(a: i32) -> impl Fn(i32) -> i32 {
        if a > 0 {
            move |b| a + b
        } else {
            move |b| a - b
        }
    }
    

    在这里,没有单一的返回类型;每个闭包都有一个独特的、不可命名的类型。

  3. 无论出于何种原因,您都需要能够命名返回的类型:

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

    您不能 ( yet ) 使用 impl SomeTrait 作为变量类型。

在这些情况下,您需要使用间接寻址。常见的解决方案是特征对象,如the other answer 中所述。 .

关于rust - 从函数返回闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25445761/

相关文章:

rust - 重命名带有连字符的 crate 不再编译

json - 无法解析 `Responder<' _, '_>` 未针对 `rocket_contrib::json::Json<MyStruct>` 实现

rust - 性能分析

generics - 我如何在 Rust 中编写一个函数来接受其 Item 满足特征的任何迭代器?

data-structures - 如何在不需要分配给新变量的情况下为链表实现前置?

rust - 在 Rust "macro_rules"宏中的调用站点使用本地绑定(bind)

rust - 将当前目录中的所有文件内容读取到向量

rust - 非穷举匹配 i32 即使它是

compiler-errors - 为什么在方法签名中使用 hyper::Client 时会出现错误 "wrong number of type arguments"?

macros - 如何将Rust宏变量嵌入文档中?