What is the difference between "generic parameters of trait function" and "generic parameters of trait"?

Viewed 184

A simple example for generic parameters of trait function:

trait Ext: Sized {
    fn then<R>(self, f: fn(Self) -> R) -> R {
        f(self)
    }
}

impl<T> Ext for T {}

A simple example for generic parameters of trait:

trait Ext<R>: Sized {
    fn then(self, f: fn(Self) -> R) -> R {
        f(self)
    }
}

impl<T, R> Ext<R> for T {}

What's the difference between the two?

When should I use "generic parameters of trait function" and when should I use "generic parameters of trait"?

1 Answers

If you use a generic parameter on a trait, then the same value will have to apply to all functions in the trait implementation, rather only apply to each function, but you'll also have to specify the parameter whenever referencing the trait.

One advantage of this is that you can implement a trait for a specific value of that trait parameter, where each implementation is independent:

impl Ext<String> for Something { }
impl Ext<u32> for Something { }

It's also possible to restrict types based on a trait parameter. For example, for the Mul trait:

pub trait Mul<Rhs = Self> {
    type Output;
    pub fn mul(self, rhs: Rhs) -> Self::Output;
}

The implementation for a specific type will determine the type of Self, and it must specify Self::Output (which doesn't have to be the same as type). The trait parameter here is ensuring that the type of rhs is the same as Self

Related