Rust:实现通用特征时的E0562

时间:2020-09-04 19:12:04

标签: generics rust traits

到目前为止,我正在尝试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的答案(谢谢!),可惜这对我不起作用(这就是为什么我尚未接受此答案的原因)。

See this playground

当尝试使用实现Ok(...)的类型返回IntoResponse时,出现以下错误:

  |
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<()>`

即使我为IntoResponse实现了Response

trait IntoResponse{
    fn foo(&self);
}

impl IntoResponse for Response<()>
{
    fn foo(&self) {}
}

我想念什么?

1 个答案:

答案 0 :(得分:0)

新答案

感觉就像您在寻找Existential types

目前,无法从特征实现中返回impl Trait类型。这是RFC修复<...>

的巨大限制

Existential types RFC已合并,但实现不稳定。您可以跟踪进度there

原始答案

您不能在那里使用impl,但是可以通过以下方式解决它:

Playground

impl<T: IntoResponse> Handler<T, Body, MyError> for GQLHandler {
    fn run(&mut self, req: http::Request<Body>) -> Result<T, MyError> {
        // ...
    }
}