在另一个异步函数中调用异步函数的正确方法是什么?

What's the proper way to call a async function in another async function?

我尝试用 actix-web 编写我的第一个 Rust Web 演示。我复制了actix-web欢迎网页中的例子,改成如下:

use actix_web::{get, App, HttpRequest, HttpServer, Responder};
use std::io::Result;

#[get("/{name}")]
async fn greet(req: HttpRequest) -> impl Responder {
    let name = req.match_info().get("name").unwrap_or("World");
    format!("Hello {}!", &name)
}

#[get("/")]
async fn greet2(req: HttpRequest) -> impl Responder {
    greet(req)
}

#[actix_web::main]
async fn main() -> Result<()> {
    HttpServer::new(|| App::new().service(greet).service(greet2))
        .bind(("127.0.0.1", 8080))?
        .run()
        .await
}

我试图在另一个异步函数“greet2”中调用异步函数“greet”并遇到编译错误:

   Compiling rust-http-demo v0.1.0 (/Users/xxx/codes/practice/rust-http-demo)
error[E0618]: expected function, found `greet`
  --> src/main.rs:12:5
   |
4  | #[get("/{name}")]
   | ----------------- `greet` defined here
...
12 |     greet(req)
   |     ^^^^^-----
   |     |
   |     call expression requires function

For more information about this error, try `rustc --explain E0618`.
error: could not compile `rust-http-demo` due to previous error

我意识到异步函数不能像普通函数一样被调用,但是编译器的信息让我很困惑。这是什么意思,我该如何解决?

一个异步函数returns一个Future,你需要await未来才能得到结果。在你的情况下 Responder:

#[get("/")]
async fn greet2(req: HttpRequest) -> impl Responder {
    greet(req).await
}

但是这可能还不够。 get is a macro that modifies your function definition. Look source.

你不能调用它本身。最好在宏封装调用之外进行实现:

async fn greet_prime(req: HttpRequest) -> impl Responder {
    let name = req.match_info().get("name").unwrap_or("World");
    format!("Hello {}!", &name)
}

#[get("/{name}")]
async fn greet(req: HttpRequest) -> impl Responder {
    greet_prime(req).await
}

#[get("/")]
async fn greet2(req: HttpRequest) -> impl Responder {
    greet_prime(req).await
}