Enforcing Supertrait functions on derived impl?

I just started with Rust and came across this problem. Is there a way to enforce the supertrait on the derived implementation? Or is there any kind of trait grouping?

In this specific case I want to implement a trait which bundles all the basic operator overloadings aka. + – * / += … and use this trait on different implementations.

Example not acutally valid code:

//grouping of traits
trait Number: std::ops::Add + std::ops::Sub .... { }

#[derive(Debug)]
struct Complex {
    re: f64,
    im: f64
}

impl Number for Complex {
    // ---snip----
}

//usage
fn main() {
    let a = Complex { re: 1.0, im: 2.0 };
    let b = Complex { re: 3.0, im: 4.0 };
    println!("Result of a + b = {:?}", a + b);
}

As I currently understand the supertrait topic I am only able to use those overloaded operators INSIDE the trait definition of the subtrait, is this correct?

Is there any other way to "group" traits like the operator overloading traits to use as a single traitlike entity?

Thanks

>Solution :

Generally when creating a supertrait, you define the trait with the given subtraits:

// Grouping of traits
trait Number
where
    Self: std::ops::Add<Output = Self> + std::ops::Sub<Output = Self> + Sized
{}

And then you implement that trait for any type that also implements the given subtraits:

impl<T> Number for T
where
    T: std::ops::Add<Output = T> + std::ops::Sub<Output = T> + Sized
{}

Then you can use it like so:

fn add<T: Number>(a: T, b: T) -> T {
    a + b
}
fn sub<T: Number>(a: T, b: T) -> T {
    a - b
}

But you’ll still need to implement all of the subtraits for any type that you want to use the supertrait with.

playground

Leave a Reply