2

In general, I want to have a trait(Requestor) which contain one method returning a T in another trait(ResponseWriter).

I searched Google and tried to find the documents, but I can'f find the right syntax for my situation. The compiler says:

T: ResponseWriter;
   |                ^^^^^^^^^^^^^^ expected 1 type argument

However, I can't write T: ResponseWriter<U> instead, it will give me other errors.

So my question is what's the correct the syntax?

    pub trait ResponseWriter<T> {
        fn get_result(&self) -> T;
    }

    pub trait Requestor {
        fn process<T>(&self) -> T
        where
            T: ResponseWriter;
    }

    pub struct Request {
        pub x: String,
    }

    impl Requestor for Request {
        fn process<T>(&self) -> T {
            Response {
                res: format!("{} {}", self.x, "world".to_owned()),
            }
        }
    }

    pub struct Response<T> {
        pub res: T,
    }

    impl<T> ResponseWriter<T> for Response<T> {
        fn get_result(&self) -> T {
            self.res
        }
    }

    let request = Request {
        x: "hello".to_owned(),
    };
    println!("{}", request.process().get_result());
pellucid
  • 251
  • 1
  • 2
  • 13
  • 3
    Generic parameters are chosen by the _caller_ of a function. The implementation of `Requestor::process()` for `Request` returns the concrete type `Response`, while pretending to be able to return any type `T` provided by the caller of the function. I don't fully understand your intentions here, but you probably want to use associated types instead of generic type parameters. – Sven Marnach Jan 11 '21 at 08:37
  • [This question](https://stackoverflow.com/questions/32059370/when-is-it-appropriate-to-use-an-associated-type-versus-a-generic-type) might help. – Jmb Jan 11 '21 at 08:43
  • Thanks a lot. Associated types is truely what I need indeed. – pellucid Jan 11 '21 at 08:58

1 Answers1

2

The code can be rewrote by the associated types. It perfectly fixes the issue and simplified the code.

    pub trait Requestor {
        type Output;

        fn process(&self) -> Self::Output;
    }

    pub struct Request {
        pub x: String,
    }

    impl Requestor for Request {
        type Output = String;

        fn process(&self) -> String {
            format!("{} {}", self.x, "world".to_owned())
        }
    }

    let request = Request {
        x: "hello".to_owned(),
    };
    println!("{}", request.process());

pellucid
  • 251
  • 1
  • 2
  • 13