Implement Rust trait for all types that have another trait
Simon Shine

Simon Shine @sshine

About: I like purely functional programming and declarative domain-specific languages, especially query languages and infrastructure specification languages.

Location:
Copenhagen, Denmark
Joined:
Aug 19, 2019

Implement Rust trait for all types that have another trait

Publish Date: Feb 15 '22
10 0

Rust traits are powerful. A particularly neat thing you can do is implement a trait for several types at once. To give a simple example, a trait for squaring numbers mainly depends on multiplying them:

trait Square {
    fn square(&self) -> Self;
}
Enter fullscreen mode Exit fullscreen mode

We could implement this trait for a single type like so:

impl Square for u64 {
    fn square(&self) -> Self {
        self * self
    }
}
Enter fullscreen mode Exit fullscreen mode

But instead of adding impl Square for ... for each type we want to .square(), this impl can be generalised to all types that impl Mul:

impl<T: Mul<Output = T> + Copy> Square for T {
    fn square(&self) -> Self {
        *self * *self
    }
}
Enter fullscreen mode Exit fullscreen mode

The key here is impl<T: ...> Square for T { ... }, that is, for T, the type that the impl takes as parameter. When eventually the constraints on T become too many, they can be moved to a where clause:

impl<T> Square for T
where
    T: Mul<Output = T> + Copy,
{
    fn square(&self) -> Self {
        *self * *self
    }
}
Enter fullscreen mode Exit fullscreen mode

Here's an example of .square() being used for multiple types that already impl Mul:

fn main() {
    println!(
        "{}, {}, {}, {}",
        10u8.square(),
        3u16.square(),
        4u32.square(),
        5u64.square()
    );
}
Enter fullscreen mode Exit fullscreen mode

Comments 0 total

    Add comment