1

Looking at these two methods:

fn m1<T: 'static + Fn(&Request) -> Response + Send + Sync>(&mut self, handler: T) {
    // It is not important
}

// Same trait bound to the generic
fn m2<T: 'static + Fn(&Request) -> Response + Send + Sync>(&mut self, handler: T) {
    // It is not important
}

Both share the same bound:

<T: 'static + Fn(&Request) -> Response + Send + Sync>

Can I "factorize" this? I tried to search the docs, but maybe I'm not using the right words. Can someone redirect me to the relevant part of the docs (or write an answer here if needed)?

Lukas Kalbertodt
  • 79,749
  • 26
  • 255
  • 305
rap-2-h
  • 30,204
  • 37
  • 167
  • 263
  • @Shepmaster More info (more text) in this question and this answer. Maybe it could help some people to find their answer (I searched and did not found as I said in my question). I think it's not a "duplicate" but a "similar". What do you think? – rap-2-h Aug 29 '16 at 15:36

1 Answers1

4

You can create a helper trait which you can use as a shorthand notation:

trait HandlerFun : 'static + Fn(&Request) -> Response + Send + Sync {}

impl<T> HandlerFun for T 
    where T: 'static + Fn(&Request) -> Response + Send + Sync 
{}

// later
fn m1<T: HandlerFun>(&mut self, handler: T) {}

However, this isn't used very often due to it's verbosity. In fact, I've never seen a private trait "alias" in any production code. It also introduces some indirection for the reader as they have to look up how HandlerFun is defined. But sometimes it makes perfect sense to use such an "empty" trait to group some other traits; in that case it's also often useful to make it public.

Note: in your original code you should have used the where notation. The inline notation <T: BoundA + BoundB> should only be used for small trait bounds. Your bound is pretty long, so the where notation is better.

Lukas Kalbertodt
  • 79,749
  • 26
  • 255
  • 305