我正在试用 Rust 并且 ❤️ 到目前为止。
但目前我被通用特征困住了:)
现状:
有一个我想实现的特性,我不能修改它:
pub trait Handler<R, B, E> {
fn run(&mut self, event: http::Request<B>) -> Result<R, E>;
}
同一库中该特征的一个实现是:
impl<Function, R, B, E> Handler<R, B, E> for Function
where
Function: FnMut(http::Request<B>) -> Result<R, E>,
{
fn run(&mut self, event: http::Request<B>) -> Result<R, E> {
(*self)(event)
}
}
这个实现可以按如下方式使用:
fn handler(req: http::Request<Body>) -> Result<impl IntoResponse, MyError> {
...
}
使用 IntoReponse
特性:
pub trait IntoResponse {
fn into_response(self) -> Response<Body>;
}
我想做什么:
我想为能够与上述类型一起使用的结构实现该特征。
我试过:
impl Handler<impl IntoResponse, Body, MyError> for GQLHandler {
fn run(&mut self, req: http::Request<Body>) -> Result<impl IntoResponse, MyError> {
...
}
}
但这会导致错误:
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
--> handlers/gql.rs:18:14
|
18 | impl Handler<impl IntoResponse, Body, NowError> for GQLHandler {
| ^^^^^^^^^^^^^^^^^
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
--> handlers/gql.rs:19:59
|
19 | fn run(&mut self, req: http::Request<Body>) -> Result<impl IntoResponse, NowError> {
| ^^^^^^^^^^^^^^^^^
如果我为特定类型实现它,它就会起作用,例如
impl Handler<http::Response<Body>, Body, NowError> for GQLHandler {
fn run(&mut self, req: http::Request<Body>) -> Result<http::Response<Body>, NowError> {
但我想以某种方式保留impl Trait
。
期待任何建议。
感谢和欢呼 托马斯
编辑:
跟进@MaxV 的回答(谢谢!),遗憾的是这对我不起作用(这就是为什么我还没有接受这个答案)。
当尝试使用实现 IntoResponse
的类型返回 Ok(...)
时,出现以下错误:
|
3 | impl<T: IntoResponse> Handler<T, Body, MyError> for GQLHandler {
| - this type parameter
4 | fn run(&mut self, req: Request<Body>) -> Result<T, MyError> {
5 | Ok(Response::<()>::new(()))
| ^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found struct `http::Response`
|
= note: expected type parameter `T`
found struct `http::Response<()>`
即使我为 Response
实现了 IntoResponse
:
trait IntoResponse{
fn foo(&self);
}
impl IntoResponse for Response<()>
{
fn foo(&self) {}
}
我错过了什么?
最佳答案
新答案
感觉是在找Existential types :
Right now, it isn't possible to return an
impl Trait
type from a trait implementation. This is a huge restriction which this RFC fixes <...>
Existential types RFC已合并,但实现并不稳定。可以跟踪进度there .
原始答案
你不能在那里使用 impl
但你可以这样解决:
impl<T: IntoResponse> Handler<T, Body, MyError> for GQLHandler {
fn run(&mut self, req: http::Request<Body>) -> Result<T, MyError> {
// ...
}
}
关于generics - Rust:实现通用特征时出现 E0562,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63746854/