Traits: Associated Types vs Type Params


#1

Hey there.

Often it’s possible to use either generic type params or associated types.

What are some guidelines for when to use which?


#2

I think it’s described pretty well in the motivation of the RFC:

Type parameters to traits can either be “inputs” or “outputs”:

  • Inputs. An “input” type parameter is used to determine which impl to use.
  • Outputs. An “output” type parameter is uniquely determined by the impl, but plays no role in selecting the impl.

There’s much more to read there, but basically what we have now is that type parameters should be used for inputs, and associated types for outputs.


#3

In other words, if it makes sense to implement the same trait for the same type with two different values of the parameter, make it a generic parameter. Otherwise, make it an associated type and get better type inference.


#4

One recurring pattern is that type parameters on the Self type are often associated types on a trait it implements:

trait Find {
    type Item;
    fn find(&self, item: &Self::Item) -> Option<usize>;
}

impl Find for Vec<T> {
    type Item = T;
    fn find(&self, item: &Self::Item) -> Option<usize> { unimplemented!() }
}

because: if Self is Vec<T>, the element type is determinate, it is T.