首页 > 解决方案 > Rust 中将函数转换为 trait 的机制是什么?

问题描述

来自 actix-web的示例如下:

use actix_web::{web, App, Responder, HttpServer};

async fn index() -> impl Responder {
    "Hello world!"
}

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new().service(
            web::scope("/app").route("/index.html", web::get().to(index)),
        )
    })
    .bind("127.0.0.1:8088")?
    .run()
    .await
}

我的问题是关于该语句to(index)在 Rust 中的工作方式。

查看源代码to我们看到:

pub fn to<F, T, R, U>(mut self, handler: F) -> Self
where
    F: Factory<T, R, U>,
// --- snip

其中Factory定义为

pub trait Factory<T, R, O>: Clone + 'static
where
    R: Future<Output = O>,
    O: Responder,
{
    fn call(&self, param: T) -> R;
}

函数async fn index() -> impl Responder转换为的机制是什么Factory<T, R, O>

标签: rustactix-web

解决方案


在您的代码段之后有一个特征的实现:

impl<F, R, O> Factory<(), R, O> for F
where
    F: Fn() -> R + Clone + 'static,
    R: Future<Output = O>,
    O: Responder,
{
    fn call(&self, _: ()) -> R {
        (self)()
    }
}

这可以理解为:如果一个类型F实现了Fn() -> Future<Output = impl Responder> + ...,那么它也实现了Factory<(), _, _>.

anasync fn是函数的语法糖,它返回Future某种类型的 a (并且可以在.await内部使用),所以async fn index() -> impl Responder实现Fn() -> impl Future<Output = impl Responder>所以它也实现Factory<(), _, _>.


推荐阅读