如何在向量中存储来自 2 个具有相同签名的不同异步函数的 Futures

how to store Futures from 2 different async functions with equal signatures in vector

如何在向量中存储来自 2 个具有相同签名的不同异步函数的 Futures?

我在不同的 crate 中有 2 个函数:

板条箱 1:

pub async fn resolve(
    client: &String,
    site: &String,
    id: &String,
) -> Result<String, Box<dyn std::error::Error>> {
    ...
    return Ok("".parse().unwrap());
}

板条箱 2:

pub async fn resolve(
    client: &String,
    site: &String,
    id: &String,
) -> Result<String, Box<dyn std::error::Error>> {
    ...
    return Ok("".parse().unwrap());
}

我尝试像这样汇总函数调用的结果:

let mut futures : Vec<_> = Vec::new();
for i in 0..self.settings.count {
    futures.push(
        crate1::resolve(
            &self.settings.filed1,
            &self.settings.filed2,
            &product.id,
        )
    );

    futures.push(
        crate2::resolve(
            &self.settings.filed1,
            &self.settings.filed2,
            &product.id,
        )
    );
}

但我明白了:

error[E0308]: mismatched types
   --> src\client.rs:124:17
    |
124 | /                 crate2::resolve(
125 | |                     &self.settings.filed1,
126 | |                     &self.settings.filed2,
127 | |                     &product.id,
128 | |                 )
    | |_________________^ expected opaque type, found a different opaque type
    |
note: while checking the return type of the `async fn`
   --> src\crate1.rs:97:6
    |
97  | ) -> Result<String, Box<dyn std::error::Error>> {
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, expected opaque type
note: while checking the return type of the `async fn`
   --> src\crate2.rs:17:6
    |
17  | ) -> Result<String, Box<dyn std::error::Error>> {
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, found opaque type
    = note: expected opaque type `impl futures::Future` (opaque type at <src\crate1.rs:97:6>)
               found opaque type `impl futures::Future` (opaque type at <src\crate2.rs:17:6>)
    = help: consider `await`ing on both `Future`s
    = note: distinct uses of `impl Trait` result in different opaque types

为什么 rust 不能推断类型?

Rust 可以 推导出类型,它只是将 impl Future 的任何 2 次使用(这就是 async fn 脱糖)视为不同的类型。

为了说明,请考虑以下函数:

async fn f1() {
  println!("f1");
}

async fn f2() {
  let a: Foo = another_future().await;
  let b: Bar = anoter_future_2().await;

  println!("f2: {} {}", a, b);
}

Rust 将(非常粗略地说)将这些重写为状态机:

enum f1_StateMachine {
  Done  // only one state because no await points
}

enum f2_StateMachine {
  AfterFirstAwait(a: Foo),
  AfterSecondFuture(b: Bar),
  Done,
}

impl Future for f1_StateMachine { ... }
impl Future for f2_StateMachine { ... }

这些显然不是同一种类型,所以不能在Vec中一起使用。任何时候你想让 Vec 包含多个不同的类型,它们都实现相同的特征,你可以使用特征对象,并将期货放在 Box.

注意,盒装期货可能有点棘手,这个 SO 答案可能有助于阅读: