Is there a simpler way to implement this function?

Total newbie here, trying to create a simple generic function that returns a product of two numbers. The following two functions do work, but is there a simpler way to accomplish this:

fn product_ref<T>(x: &T, y: &T) -> T 
where T: std::ops::Mul<Output = T>,
    T: std::marker::Copy
{
   (*x) * (*y)
}

fn product<T>(x: T, y: T) -> T 
where T: std::ops::Mul<Output = T>,
    T: std::marker::Copy
{
   x * y
}

    let x = 4;
    let y = 5;
    print!("product1={}\n", product(x, y));
    print!("product2={}\n", product_ref( &x, &y));

One more thing: is there a way to combine several traits which are commonly used together in a thing called Number, so that we could just say where T: Number instead of listing that we can copy, add, multiply this T and so on. TIA!

You could do

fn product<T: Mul<U>, U>(x: T, y: U) -> T::Output {
   x * y
}

// ...

    print!("product1={}\n", product(x, y));
    print!("product1={}\n", product(&x, y));
    print!("product1={}\n", product(x, &y));
    print!("product1={}\n", product(&x, &y));

Playground. T::Output here is short for <T as Mul<U>>::Output. (The short form can be used here because it's unambiguous given the trait bounds.)


For the trait question generally, you can create a new trait with your desired traits as supertraits:

trait MyOps: Mul<Self, Output = Self> + Add<Self, Output = Self> + /* ... */
// Alternatively spelled
trait MyOps
where
    Self: Mul<Self, Output = Self>,
    Self: Add<Self, Output = Self>,
    // ...
{ /* ... */ }

And then implement it for everything that matches the bounds:

impl<T> MyOps for T
where
    Self: Mul<Self, Output = Self>,
    // ...
{ /* ... */ }

For the number traits specifically, see the num crate, e.g. NumOps.

2 Likes

That was helpful, TY!