0

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

我在不同的箱子中有 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不能推断类型?

4

1 回答 1

0

Rust可以推断出类型,它只是将任何 2 次使用impl Future(这是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 { ... }

这些显然不是同一类型,因此不能在 a 中Vec一起使用。与任何时候你想要一个Vec包含多个不同类型都实现相同特征一样,你可以使用一个特征对象,并将期货放在一个Box.

请注意,盒装期货可能有点棘手,这个 SO 答案可能有助于阅读:如何等待盒装未来的结果?

于 2021-11-18T20:43:11.273 回答