简体   繁体   English

Rust 预期类型发现结构

[英]Rust expected type found struct

I've got the following code:我有以下代码:

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

use actix_router::{Path, Url};
use actix_web::dev::{ServiceRequest, ServiceResponse};
use actix_web::error::ResponseError;
use actix_web::{http, http::StatusCode, Error, HttpRequest, HttpResponse};

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

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        let app = App::new()
            .wrap_fn(|req, srv| {
                let passed: bool;

                // change to false to simulate a failed check
                let check = true;

                if *&req.path().contains("/item/") {
                    passed = check;
                } else {
                    passed = true;
                }

                let fresh_result = match passed {
                    true => {
                        let fut = srv.call(req);
                        Box::pin(async {
                            let result = fut.await?;
                            Ok(result)
                        })
                    }
                    false => Box::pin(async {
                        let result = req.into_response(
                            HttpResponse::Found()
                                .header(http::header::LOCATION, "/login")
                                .finish()
                                .into_body(),
                        );
                        Ok(result)
                    }),
                };
                async {
                    let last_outcome = fresh_result.await?;
                    Ok(last_outcome)
                }
            })
            .route("/", web::get().to(greet));
        return app;
    })
    .bind("127.0.0.1:8000")?
    .run()
    .await
}

However, I get the following error:但是,我收到以下错误:

110 |                         let fresh_result = match passed {
    |    ________________________________________-
111 |   |                         true => {
112 |   |                             let fut = srv.call(req);
113 |   |                             Box::pin(
    |  _|_____________________________-
114 | | |                                 async {
115 | | |                             let result = fut.await?;
116 | | |                             Ok(result)
117 | | |                             }
118 | | |                             )
    | |_|_____________________________- this is found to be of type `std::pin::Pin<std::boxed::Box<impl core::future::future::Future>>`
...     |
121 | / |                             Box::pin(
122 | | |                             async {
123 | | |                             let result = req.into_response(
124 | | |                                 HttpResponse::Found()
...   | |
129 | | |                             }
130 | | |                             )
    | |_|_____________________________^ expected generator, found a different generator
131 |   |                         }
132 |   |                     };
    |   |_____________________- `match` arms have incompatible types
    | 
   ::: /Users/maxwellflitton/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/src/libcore/future/mod.rs:55:43
    |
55  |     pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
    |                                               ------------------------------- the found opaque type
    |
    = note: expected type `std::pin::Pin<std::boxed::Box<impl core::future::future::Future>>` (generator)
             found struct `std::pin::Pin<std::boxed::Box<impl core::future::future::Future>>` (generator)

I am completely stuck on this.我完全坚持这一点。 I don't know how to ensure it's a type.我不知道如何确保它是一种类型。 If there is no match statement and there is just one async block then it all runs fine.如果没有 match 语句并且只有一个 async 块,那么一切都运行良好。 This is for middleware in an Actix-web server.这是用于 Actix-web 服务器中的中间件。 I am trying to redirect the viewer if credentials are not working.如果凭据不起作用,我正在尝试重定向查看器。

You use Box::pin to create the boxed futures, but Rust still thinks you want the impl Future<...> version (meaning the future is boxed to the heap, but doesn't use dynamic dispatch).你使用Box::pin创建盒装期货,但 Rust 仍然认为你想要impl Future<...>版本(意味着未来被盒装到堆中,但不使用动态调度)。

This is why the type in the error is Pin<Box<impl Future<...>>> , and because any two impl Future<...> s are of different types, you get the expected/found error.这就是错误中的类型是Pin<Box<impl Future<...>>> ,并且因为任意两个impl Future<...> s 是不同的类型,您会得到expected/found错误。

You need to tell Rust you are interested in dynamic dispatch (because you have two different futures that can be stored in the Box , and which one really is stored there can only be known at runtime), for example by explicitly specifying the return type like this:你需要告诉 Rust 你对动态调度感兴趣(因为你有两个不同的 futures 可以存储在Box ,而哪个真正存储在那里只能在运行时知道),例如通过显式指定返回类型,如这个:

use std::pin::Pin;
use std::future::Future;

let fresh_result: Pin<Box<dyn Future<Output=_>>> = match passed {
    // ...
}

Now you will get a new error about cannot infer type for type parameter E which can be resolved by specifying the Output of the future as well, so the new line should be:现在你会得到一个关于cannot infer type for type parameter E的新错误,这也可以通过指定未来的Output来解决,所以新行应该是:

let fresh_result: Pin<Box<dyn Future<Output=Result<ServiceResponse, Error>>>> = match passed {
    // ...
}

which will compile successfully!这将成功编译!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Rust 显示预期特征 object `dyn Future`,在传递 function 作为参数时发现不透明类型 - Rust showing expected trait object `dyn Future`, found opaque type when passing function as a param F#预期的类型列表,但此处具有类型[] - F# Expected type List but here has type [] 在 Rust 中将其作为函数参数传递时如何为 futures_intrusive::sync::GenericSemaphore 指定类型 - How to specify type to a futures_intrusive::sync::GenericSemaphore when passing it down as a function parameter in Rust 在类型上找不到具有正确签名的方法SignInProcedure - No method SignInProcedure with correct signature found on type 找不到类型或名称空间名称AsyncLocal &lt;&gt; - The type or namespace name AsyncLocal<> could not be found Xamarin / IOS / Azure - 在类型上找不到&#39;id&#39;成员 - Xamarin / IOS / Azure - No 'id' member found on type F#-该类型应具有Async &lt;&#39;a&gt;类型,但应具有字符串-&gt; Asnyc &lt;&#39;a&gt; - F# - The type was expected to have type Async<'a> but has string -> Asnyc<'a> instead 减速器接收到的先前状态具有意外的“功能”类型。 预期参数为具有以下键的对象:“注册” - The previous state received by the reducer has unexpected type of “Function”. Expected argument to be an object with the following keys: “register” 为什么在 Result 上使用 match 语句会出现“预期类型 Future”错误? - Why do I get “expected type Future” error using match statement on Result? Rust - 在闭包中返回未来 - Rust - return a future in a closure
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM