Rust : 일반 특성을 구현할 때 E0562

Sep 05 2020

나는 지금까지 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어떻게 든 유지하고 싶습니다 .

어떤 제안이라도 기다리고 있습니다.

감사합니다 & 건배 Thomas

편집하다:

@MaxV의 답변 (감사합니다!)에 이어 슬프게도 저에게 효과가 없었습니다 (아직이 답변을 수락하지 않은 이유입니다).

이 놀이터보기

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) {}
}

내가 무엇을 놓치고 있습니까?

답변

MaxV Sep 05 2020 at 04:16

새로운 답변

Existential 유형을 찾고있는 것 같습니다 .

지금 impl Trait은 특성 구현에서 유형 을 반환 할 수 없습니다 . 이것은이 RFC가 수정하는 큰 제한 사항입니다. <...>

기존 유형 RFC 가 병합되었지만 구현이 안정화되지 않았습니다. 거기 에서 진행 상황을 추적 할 수 있습니다 .

원래 답변

impl거기에서 사용할 수는 없지만 다음과 같이 해결할 수 있습니다.

운동장

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