Generic arithmetic with std::ops::Add?


#1

Hi,

Hi, i am totally new to Rust, coming from a background in C# Java and C++. I find many of Rusts concepts quite innovative, but i am also having some trouble getting them working, so i was hoping i could find a little bit of help here.

So, this is probably a really stupid question, but i would like to understand why the following isn’t valid (which is something i cannot do in C# and its been annoying me for a while):

use std::ops::Add;

fn foo<T:Add>(x : T) -> T{
    return x + x;
}

fn main() {
    foo(42);
}

It produces a “mismatched types” error.


#2

The result type of an addition is not necessarily the same type as the operands.

For that reason, there’s an associated type called Output in the Add trait that denotes the output or result type.
You have to use that type as return type of your function.


#3

You can also require matching output up front with T:Add<Output=T>.

But note that x + x is also a problem, because you’re moving the same x by value in two places. This is fine if you also require T:Copy, or else you can require T:Clone and use x.clone() + x.

Or you can add by reference, something like:

fn foo<'a, T>(x: &'a T) -> T
where &'a T: Add<&'a T, Output=T>
{
    x + x
}

#4

You can write:

use std::ops::Add;

fn double_it<T>(x: T) -> T
where T: Add<Output=T> + Copy + Clone {
    x + x
}

fn main() {
    println!("{}", double_it(21));
}

#5

Thanks for all the replies, good to see Rust has a friendly community. It makes sense that it needs Copy, though the syntax for setting Output from Add is a bit surprising :slight_smile: Really nice to be able to do this, i cannot do it in either F# or C#.


#6

Thank you.