Rust: Genel özelliği uygularken E0562

Sep 05 2020

Rust'ı deniyorum ve şimdiye kadar ❤️.

Ama şu anda genel özelliklerle sıkışıp kaldım :)

Statüko:

Uygulamak istediğim ve değiştiremeyeceğim bir özellik var:

pub trait Handler<R, B, E> {
    fn run(&mut self, event: http::Request<B>) -> Result<R, E>;
}

Aynı kütüphanede bu özelliğin bir uygulaması:

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

Ve bu uygulama şu şekilde kullanılabilir:

fn handler(req: http::Request<Body>) -> Result<impl IntoResponse, MyError> {
    ...
}

İle IntoReponseözelliğin:

pub trait IntoResponse {
    fn into_response(self) -> Response<Body>;
}

Yapmak istediğim şey:

Bir yapının yukarıda bahsedilen tiplerle kullanılabilmesi için bu özelliği uygulamak istiyorum.

Denedim:

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

Ancak bu, hatalarla sonuçlanır:

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> {
   |                                                           ^^^^^^^^^^^^^^^^^

Belirli bir tür için uygularsam, işe yarıyor, örneğin

impl Handler<http::Response<Body>, Body, NowError> for GQLHandler {
    fn run(&mut self, req: http::Request<Body>) -> Result<http::Response<Body>, NowError> {

ama bir impl Traitşekilde tutmak isterim .

Herhangi bir öneriyi dört gözle bekliyorum.

Teşekkürler ve Şerefe Thomas

DÜZENLE:

@ MaxV'in cevabını takiben (Teşekkürler!), Ne yazık ki bu benim için işe yaramadı (bu yüzden bu cevabı henüz kabul etmedim).

Bu oyun alanını görün

Bir Ok(...)tür uygulama ile geri dönmeye çalışırken IntoResponse, aşağıdaki hatayı alıyorum:

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

IntoResponseiçin uyguladığım halde Response:

trait IntoResponse{
    fn foo(&self);
}

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

Neyi kaçırıyorum?

Yanıtlar

MaxV Sep 05 2020 at 04:16

Yeni cevap

Varoluşsal türleri arıyormuşsunuz gibi geliyor :

Şu anda, impl Traitbir özellik uygulamasından bir tür döndürmek mümkün değil . Bu, bu RFC'nin düzelttiği çok büyük bir kısıtlamadır <...>

Varoluşsal tipler RFC birleştirildi, ancak uygulama stabilize edilmedi. Orada ilerlemeyi takip edebilirsiniz .

Orijinal cevap

implOrada kullanamazsınız ama şu şekilde çözebilirsiniz:

Oyun alanı

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