我有一个用actix-web编写的小后端应用程序.我想有一个类似于下面的函数.

async fn function(var: bool) -> impl Responder {
    if var {
        Redirect::to("link")
    } else {
        NamedFile::open_async("/file").await
    }
}

错误:`if` and `else` have incompatible types expected `Redirect`, found future.

我认为这可能可以通过将文件读入字符串并使用HttpResponse来实现.但是,既然NamedFile实现了Responder,那么它是否可能在这种设置中工作?

如果go 掉if—else,这些都是有效的返回类型,但if—else语句的返回类型必须匹配.那么,在这种情况下,有没有可能不使用if—else?

编辑:链接的解决方案在这种情况下不起作用.将impl Responder更改为Box<dyn Responder>会导致trait bounds失败.我收到以下错误消息:

the trait bound `std::boxed::Box<(dyn actix_web::Responder + 'static)>: actix_web::Responder` is not satisfied 

也许它可以修复,但我没有足够的Rust泛型经验来做到这一点.

推荐答案

动态分派不能与Responder一起工作,但还有两个其他解决方案.

第一种是使用Either,也通过转发到活动变体来实现Responder:

use actix_web::Either;

async fn function(var: bool) -> impl Responder {
    if var {
        Either::Left(Redirect::to("link"))
    } else {
        Either::Right(NamedFile::open_async("/file").await)
    }
}

第二种 Select ,如你所说,是将它们转换为HttpResponse.他们有不同的身体类型,所以我们还需要转换身体:

async fn function(var: bool, request: HttpRequest) -> HttpResponse {
    if var {
        Redirect::to("link")
            .respond_to(&request)
            .map_into_boxed_body()
    } else {
        NamedFile::open_async("/file")
            .await
            .respond_to(&request)
            .map_into_boxed_body()
    }
}

HttpRequest是一个提取器,所以你可以在你的处理程序函数中使用这个参数.

Rust相关问答推荐

如何从Rust记录WASM堆内存使用情况?

如何最好地并行化修改同一Rust向量的多个切片的代码?

抽象RUST中的可变/不可变引用

有没有办法避免在While循环中多次borrow `*分支`

铁 rust 中的共享对象实现特征

在自定义序列化程序中复制serde(With)的行为

在析构赋值中使用一些现有绑定

我无法理解Rust范围的定义(Rust Programming Language,第二版克拉布尼克和尼科尔斯)

在macro_rule中拆分模块和函数名

失真图像图形捕获Api

UnsafeCell:它如何通知 rustc Select 退出基于别名的优化?

Rust FFI 和 CUDA C 性能差异

如何保存指向持有引用数据的指针?

注释闭包参数强调使用高阶排定特征界限

实现AsyncWrite到hyper Sender时发生生命周期错误

从光标位置旋转精灵

Rust Redis 中的 HSET 命令问题

由特征键控的不同 struct 的集合

bcrypt 有长度限制吗?

如何解析 Rust 中的 yaml 条件字段?