如何从包含未来的结果中创建未来?

How to create a Future from a Result containing a Future?

是否可以(合乎逻辑?)将包含未来的结果转换为解析为结果的未来?

以下功能有点破损,但希望能使我想要实现的目标更加清晰:

use std::future::Future;

fn transpose<T,U,E>(result: Result<T,E>) -> impl Future<Output = Result<U, E>>
   where T: Future<Output = Result<U,E>> /* not sure if this is the correct trait bound */ {
   match result {
      Ok(inner) => /* a future that eventually resolves to a Result<U, E> */
      Err(error) => /* a future that immediately resolves to a Result<U, E>::Err(error) */
   }
}

给出一些上下文:我发现自己需要在从传递给 Result::map 的闭包中调用 async 函数后执行此操作,所以也许这是我的第一个错误。

如果 resultOk 你可以简单地 return 内在的未来。但是,如果它是 Err,那么你必须构建一个新的未来解析为 Result<U, E>::Err(e)。这意味着您不能 return 通用 Future 因为两个 match 臂 return 是两种不同的类型。你必须 return 一个特征对象:

fn transpose<T, E: 'static, U: 'static>(result: Result<T, E>) -> Box<dyn Future<Output = Result<U, E>>>
   where T: Future<Output = Result<U, E>> + 'static {
   match result {
      Ok(inner) => Box::new(inner),
      Err(error) => Box::new(async { Err(error) })
  }
}

可能人们通常想要的是立即处理 Err 案例,而不是等到 .awaited 之后再处理,这样就可以解释为什么这样的功能还不存在.但是,如果您确实需要它,使用 async.await:

编写非常简单
fn transpose_flatten<T, U, E>(result: Result<T, E>) -> impl Future<Output = Result<U, E>>
where
    T: Future<Output = Result<U, E>>,
{
    async {                          // when polled,
        match result {
            Ok(good) => good.await,  // defer to the inner Future if it exists
            Err(bad) => Err(bad),    // otherwise return the error immediately
        }
    }
}

或使用 async fn 的相同事物(这并不总是完全相同的事物,但在这种情况下似乎是):

async fn transpose_flatten<T, U, E>(result: Result<T, E>) -> Result<U, E>
where
    T: Future<Output = Result<U, E>>,
{
    match result {
        Ok(good) => good.await,
        Err(bad) => Err(bad),
    }
}

由于 Err 值是从封闭的 async 块或函数返回的,您可以使用 ? 语法使其更短:

async fn transpose_flatten<T, U, E>(result: Result<T, E>) -> Result<U, E>
where
    T: Future<Output = Result<U, E>>,
{
    result?.await
}

我将此函数称为 transpose_flatten,因为对我来说 transpose 听起来应该使用 Result<Future<Output = U>, _>。此函数将两层Result(传递给函数的一层和从未来返回的一层)展平。