从函数返回一个闭包 [英] Returning a closure from a function

查看:55
本文介绍了从函数返回一个闭包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:这个问题是在 Rust 的第一个稳定版本发布之前提出的.从那以后发生了很多变化,函数中使用的语法甚至不再有效.尽管如此,谢普马斯特的回答非常好,让这个问题值得保留.

Note: This question was asked before Rust's first stable release. There have been lots of changes since and the syntax used in the function is not even valid anymore. Still, Shepmaster's answer is excellent and makes this question worth keeping.

终于有未装箱的瓶盖了,所以我正在试验它们,看看你能做什么.

Finally unboxed closures have landed, so I am experimenting with them to see what you can do.

我有这个简单的功能:

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

但是,我收到缺少生命周期说明符 [E0106] 错误.我试图通过将返回类型更改为 ||: 'static ->int,但随后出现另一个错误 由于需求冲突而无法推断适当的生命周期.

However, I get a missing lifetime specifier [E0106] error. I have tried to fix this by changing the return type to ||: 'static -> int, but then I get another error cannot infer an appropriate lifetime due to conflicting requirements.

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

If I understand correctly, the closure is unboxed so it owns a and b. It seems very strange to me that it needs a lifetime. How can I fix this?

推荐答案

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

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

这允许返回一个 unboxed 闭包,即使无法指定闭包的确切类型.

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. 您的目标是在此版本之前的 Rust

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

你不能(还没有)使用impl SomeTrait 作为变量类型.

You cannot (yet) use impl SomeTrait as a variable type.

在这些情况下,您需要使用间接寻址.常见的解决方案是 trait 对象,如另一个答案中所述.

In these cases, you need to use indirection. The common solution is a trait object, as described in the other answer.

这篇关于从函数返回一个闭包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆