Hi, I'm kinda new to Rust but I have background in other languages. On a personal project, I needed to overload operators on a generic type with trait bounds.The code below is a simplified version of code I ended up with after reading some docs, looking at examples and following compiler suggestions:
struct Num <V:, G>
where
V : ops::Neg + ops::Neg<Output = V> + ops::Add + ops::Add<Output = V>,
G: PartialEq
{
val: V,
group: G
}
impl<V,G> ops::Add for Num<V, G>
where
V : ops::Neg + ops::Neg<Output = V> + ops::Add + ops::Add<Output = V>,
G : PartialEq
{
type Output = Option<Num<V, G>>;
fn add(self, other: Self) -> Self::Output {
if self.group == other.group {
let sum = self.val + other.val;
Some(Num { val: sum, group : self.group })
} else {
None
}
}
}
impl<V,G> ops::Neg for Num<V, G>
where
V : ops::Neg + ops::Neg<Output = V> + ops::Add + ops::Add<Output = V>,
G : PartialEq
{
type Output = Num<V, G>;
fn neg(self) -> Num<V, G> {
Num { val: -self.val, group: self.group }
}
}
Short summary:
The code above defines a special type Num
which has a value and a group. The values are added normally to create a new Num
, provided the groups are equal, and the 'sum' Num
simply inherits the common group. Adding two Num
s from different groups is invalid, and therefore should return None
instead.
The negation operation only negates the value and inherits the group.
The code seems to work. However, I have a couple of questions:
- I noticed that there is a lot of repetition for the
where
clause (in the struct, and all of the overload implementations). Is there someway to make this better? - The compiler suggested adding
ops::Neg<Output = V>
andops::Add<Output = V>
.
2.a I can't seem to find what the<Output = V>
is called. It's not in the std::ops doc and other operator overloading examples on the internet.
2.b Is theOutput
in<Output = V>
related to the one intype Output = Num<V, G>;