[英]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.