扭曲和响应类型以及特征对象?

2024-05-08

我有一个扭曲拒绝处理程序,我像这样使用它,

.recover(handle_rejection)

它是这样声明的,

pub async fn handle_rejection(err: Rejection) -> Result<impl warp::reply::Reply, Infallible> {

如果两侧if语句是相同类型的,

if let Some(e) = err.find::<crate::api::error::UserError>() {
  Ok(warp::reply::with_status(
    warp::reply::reply(),
    warp::http::StatusCode::NOT_FOUND,
  ))
}
else {
  Ok(warp::reply::with_status(
    warp::reply::reply(),
    warp::http::StatusCode::NOT_FOUND,
  ))
}

一切正常,但如果改变其中一侧,

Ok(e.into_response())

不再好了,我在编译时遇到这个错误,

error[E0308]: mismatched types
  --> src/api.rs:22:8
   |
22 |                   Ok(warp::reply::with_status(
   |  ____________________^
23 | |                     warp::reply::reply(),
24 | |                     warp::http::StatusCode::NOT_FOUND,
25 | |                 ))
   | |_________________^ expected struct `Response`, found struct `WithStatus`
   |

不过我不明白,因为那一面没有改变,这应该仍然令人满意impl warp::reply::Reply,这里有什么问题?

我已经尝试过将不同的排列显式地转换为特征对象,例如as warp::reply::Reply and as &dyn warp::reply::Reply但它们也不起作用。


问题是impl Trait只是一些具体的简写 实现的类型Trait。所以这:

fn foo() -> impl Bar {}

与此相同:

fn foo() -> SomeConcreteTypeImplementingBar {}

Where SomeConcreteTypeImplementingBar自动确定(感谢@Jmb 的更正)。

虽然不正确,但将其视为以下内容可能会有所帮助:

fn foo<B: Bar>() -> B

This is not一样的,因为用户指定了类型B,不是函数,但它可能有助于演示目的。真正的目的是impl就是说“我要回来了some实现的类型Bar,但我不会告诉你那种类型是什么”。

最终,Rust 必须弄清楚返回的具体类型。但是,请考虑以下事项:

trait Bar {}

struct One;
impl Bar for One {}

struct Two;
impl Bar for Two {}

fn foo() -> impl Bar {
    if some_condition {
        One
    } else {
        Two
    }
}

编译器应该选择什么具体类型?嗯,也可以是One or Two,取决于什么some_condition是!在这种情况下,编译器不知道选择哪种类型,因此会抛出错误。

这与您遇到的错误相同。 if 语句的两个分支返回不同的类型,因此编译器会抛出错误,告诉您它期望 if 语句的两个分支的类型为结构体Response或结构体WithStatus。要解决此问题,您可以:

  • 创建一个新类型来实现Reply封装这两种情况,然后只返回该类型
  • 重新设计您的函数以仅使用一种类型。上面的选项是其中一种情况,但您也可以使用warp内置型
  • Box你的返回值。结果代码如下所示:
pub async fn handle_rejection(err: Rejection) -> Result<Box<dyn warp::reply::Reply>, Infallible> {
if let Some(e) = err.find::<crate::api::error::UserError>() {
    Ok(Box::new(e.into_response()))
} else {
    Ok(Box::new(warp::reply::with_status(
        warp::reply::reply(),
        warp::http::StatusCode::NOT_FOUND,
    )))
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

扭曲和响应类型以及特征对象? 的相关文章

随机推荐