#[derive(Copy,Clone, Debug)]
struct My<T: Sized>(T);
impl<T> Add for My<T>
where T : Sized + Add<Output = T>
{
type Output = My<T>;
fn add(self, rhs: Self) -> Self::Output
{
My(self.0 + rhs.0)
}
}
It is obvious from my code that I simply want to add two My together with the help of the Add trait. I do not understand the second part of trait bound which is Add<Output=T>. The addition of two My(T) will be My(T), but the second trait bound tells that it will be the type T referring to Output=T. However, later we use the line type Output = My<T> which seems okay to me.
Why?
Are there any easy-to-understand ways to implement the Add trait for My(T)?
T is the type of the wrapped field, i.e. self.0. If you add self.0 + rhs.0, you also get a T, which is exactly what you want, because you can then wrap it in a My. Every type checks out.
Note that the Addbound is on the wrapped type, i.e., T itself, not on My<T>.
because the trait Add has both a generic type parameter (Rhs, i.e. the other operand of the + operator, which default to Self), and an associated type (Output, which is the result of the + operator). this means, type T can have implementations for Add trait that will return result type that is different from T. so the trait bound T: Add<Output = T> restricts the generic type T to those implements Add and the return type is also T, this makes sure in your implementation, the code
My(self.0 + rhs.0)
has the correct type. otherwise, self.0 + rhs0 could be any type, so you can't use it to construct a My<T> value.