rust 为什么当我将闭包存储为变量时会出现生存期错误,而当我将其声明为表达式时却没有错误?

dpiehjr4  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(96)

我对Rust还比较陌生,在生命周期中与闭包有关的问题上还在努力,所以希望有人能在这里提供帮助。
使用AWS Rust SDK for lambda(lambda_http),以下代码无法编译。

let handler = service_fn(move |event: Request| async  {
    handler_organization_post(&shared_client, event).await
});
lambda_http::run(handler).await

字符串
它失败,并出现以下与生存期相关的错误。

error: lifetime may not live long enough
   --> organization/organization_post/src/main.rs:125:52
    |
125 |       let handler = service_fn(move |event: Request| async  {
    |  ______________________________---------------------_^
    | |                              |                   |
    | |                              |                   return type of closure `[async block@organization/organization_post/src/main.rs:125:52: 127:6]` contains a lifetime `'2`
    | |                              lifetime `'1` represents this closure's body
126 | |         handler_organization_post(&shared_client, event).await
127 | |     });
    | |_____^ returning this value requires that `'1` must outlive `'2`
    |
    = note: closure implements `Fn`, so references to captured variables can't escape the closure


但是,如果我只是将闭包声明内联到对lambda_http::run的调用中,则程序编译和运行都没有问题。

lambda_http::run(service_fn(move |event: Request| async move {
    handler_organization_post(&shared_client, event).await
})).await


在我的脑海中,这些在语义上是等同的,所以很明显我错过了一些东西,并希望在正确的方向上有一个指针。
谢了
我尝试将闭包保存到另一个变量,然后将其传递给运行时的服务函数

z4bn682m

z4bn682m1#

需要使用async move才能使闭包有效。这是两个版本的代码之间的差异-第二个版本使用async move,而第一个版本没有。
要理解这一点,回想一下async块的计算结果是impl Future-实现Future特征的某个值。块中的代码不会立即执行。它只在“轮询”未来时执行-也就是说,当有人试图评估未来并获得底层值时。
考虑一个使用async的非常简单的闭包。

let closure = |y: i32| async { y + 1 };

字符串
这实际上不是一个有效的闭包。async块没有move关键字,因此它计算的future包含对y的引用,而不是y本身。当async块被求值时,这个引用将不再有效,因为闭包将返回。要使一切正常工作,需要将代码更改为

let closure = |y: i32| async move { y + 1 };

相关问题