首页 > 解决方案 > 如何在不使用 OptionFuture 的情况下在 `Option::and_then` 或 `Option::map` 的闭包中使用 async/await?

问题描述

我想运行类似下面的代码:

async fn get_user(s: &str) -> Option<User> { /* ... */ }

let user_id = Some("sessiontoken").and_then(|session_token| {
    get_user(session_token)
        .await // <- error
        .map(|user| user.id)
});

但它不起作用,因为 await 只能在异步块或函数中使用。另一方面,如果我使用异步块,则闭包将返回impl Future<Output = Option<_>>这是不允许的,因为Option::and_then只允许Option作为返回类型。

我知道的唯一选择是使用OptionFuture,创建一个中间变量,.map而不是.and_then.

use futures::future::OptionFuture;

let user: OptionFuture<_> = Some("sessiontoken")
    .map(|session_token| {
        get_user(session_token)
    })
    .into();
let user_id = user.await.flatten().map(|user| user.id);

但这确实很麻烦,并且使我无法使用许多可以对 Options、Results 或类似内容进行操作的函数,例如Option::and_then.

没有更好的办法吗?

标签: rustasync-awaitrust-futures

解决方案


我相信惯用的方法是简单地使用match

let user_id = match session_token {
    Some(session_token) => get_user("sessiontoken").await.map(|user| user.id),
    None => None,
};

推荐阅读