我应该在 Rust 中返回 await 吗?

lap*_*tou 5 asynchronous rust

在 JavaScript 中,异步代码是用类似于 Rust 的Promise 和async/await语法编写的。当 Promise 可以简单地返回时(即,当异步函数作为另一个函数中的最后一件事执行时),返回等待 Promise通常被认为是多余的(因此不鼓励):

async function myFn() { /* ... */ }

async function myFn2() {
  // do setup work

  return await myFn()
  // ^ this is not necessary when we can just return the Promise
}
Run Code Online (Sandbox Code Playgroud)

我想知道类似的模式是否适用于 Rust。我应该更喜欢这个:

pub async fn my_function(
    &mut self,
) -> Result<()> {
    // do synchronous setup work

    self.exec_command(
        /* ... */
    )
    .await
}
Run Code Online (Sandbox Code Playgroud)

或这个:

pub fn my_function(
    &mut self,
) -> impl Future<Output = Result<()>> {
    // do synchronous setup work

    self.exec_command(
        /* ... */
    )
}
Run Code Online (Sandbox Code Playgroud)

前者对我来说更符合人体工程学,但我怀疑后者的性能可能更高。是这种情况吗?

use*_*342 3

两个变体之间的一个语义差异是,在第一个变体中,同步设置代码仅在等待返回的 future 时运行,而在第二个变体中,它将在调用函数后立即运行:

let fut = x.my_function();
// in the second variant, the synchronous setup has finished by now
...
let val = fut.await;  // in the first variant, it runs here
Run Code Online (Sandbox Code Playgroud)

为了使差异变得明显,同步设置代码必须有副作用,并且在调用异步函数和等待它返回的 future 之间需要有延迟。

除非您有特定原因立即执行前导码,否则请使用异步函数,即第一个变体。它使函数稍微更具可预测性,并且在函数重构时更容易添加更多等待。