Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >生锈:预期类型,发现不透明类型

生锈:预期类型,发现不透明类型
EN

Stack Overflow用户
提问于 2020-11-04 23:56:05
回答 1查看 3.9K关注 0票数 4

我想为在actix中呈现模板创建一个辅助函数,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fn render_response(
    tera: web::Data<Tera>,
    template_name: &str,
    context: &Context,
) -> impl Responder {
    match tera.render(template_name, context) {
        Ok(rendered) => HttpResponse::Ok().body(rendered),
        Err(_) => HttpResponse::InternalServerError().body("Failed to resolve the template."),
    }
}

我在下面的视图中使用它:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
async fn signup(tera: web::Data<Tera>) -> impl Responder {
    let mut data = Context::new();
    data.insert("title", "Sign Up");

    render_response(tera, "signup.html", &data)
}

如果视图和上面的视图一样简单,那么一切都可以正常工作,但是如果视图稍微复杂一些,我就会遇到一个问题:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
async fn login(tera: web::Data<Tera>, id: Identity) -> impl Responder {
    let mut data = Context::new();
    data.insert("title", "Login");

    if let Some(id) = id.identity() {
        return HttpResponse::Ok().body(format!("Already logged in: {}.", id));
    }

    render_response(tera, "login.html", &data)
}

我所犯的错误:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
error[E0308]: mismatched types
   --> src\main.rs:101:5
    |
42  | ) -> impl Responder {
    |      -------------- the found opaque type
...
101 |     render_response(tera, "login.html", &data)
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `actix_web::HttpResponse`, found opaque type
    |
    = note:     expected type `actix_web::HttpResponse`
            found opaque type `impl actix_web::Responder`

我尝试将return HttpResponse...提取到一个也返回impl Responder的单独函数中,但我现在得到了不同的错误:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
error[E0308]: mismatched types
   --> src\main.rs:101:5
    |
42  | ) -> impl Responder {
    |      -------------- the found opaque type
...
101 |     render_response(tera, "login.html", &data)
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found a different opaque type
    |
    = note:     expected type `impl actix_web::Responder` (opaque type at <src\main.rs:104:28>)
            found opaque type `impl actix_web::Responder` (opaque type at <src\main.rs:42:6>)
    = note: distinct uses of `impl Trait` result in different opaque types

我真的不明白为什么会发生这种事,也不明白如何解决。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-05 03:27:36

当函数返回类似impl Responder的内容时,意味着它返回实现Responder的某种类型。编译器可以推断类型,但是对任何调用者来说它都是“不透明的”,这意味着您不能假设类型实际上是什么。即使编译器有更多的信息,类型总是在函数边界上匹配的。这一点很重要,这样人类就可以在函数级别对代码进行推理,而不必将有关程序的各个行的所有信息保存在他们的头脑中。

函数还必须只返回一种类型,所以当编译器遇到这样的函数时:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
async fn login(tera: web::Data<Tera>, id: Identity) -> impl Responder {
    let mut data = Context::new();
    data.insert("title", "Login");

    if let Some(id) = id.identity() {
        return HttpResponse::Ok().body(format!("Already logged in: {}.", id));
    }

    render_response(tera, "login.html", &data)
}

它看到返回不透明impl Responder的最后一条语句和返回具体HttpResponse的早期return语句。即使您知道它们实际上是相同的类型,这只是因为您碰巧知道render_response是如何实现的。这很好,因为它可以防止代码中不相关部分的更改破坏此函数:您不希望对render_response主体的更改导致login中的类型不匹配。

render_response的返回类型更改为具体类型,它将工作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fn render_response(
    tera: web::Data<Tera>,
    template_name: &str,
    context: &Context,
) -> HttpResponse;
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64693182

复制
相关文章

相似问题

添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文