Черта, которую вы ищете, может быть найдена в num-traits crate:
pub trait NumOps<Rhs = Self, Output = Self>:
Add<Rhs, Output = Output>
+ Sub<Rhs, Output = Output>
+ Mul<Rhs, Output = Output>
+ Div<Rhs, Output = Output>
+ Rem<Rhs, Output = Output>
{
}
impl<T, Rhs, Output> NumOps<Rhs, Output> for T where
T: Add<Rhs, Output = Output>
+ Sub<Rhs, Output = Output>
+ Mul<Rhs, Output = Output>
+ Div<Rhs, Output = Output>
+ Rem<Rhs, Output = Output>
{
}
Вы можете легко использовать ее в своем типе вектора:
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Vec2<T: NumOps> {
pub x: T,
pub y: T,
}
impl<T: NumOps> Add for Vec2<T> {
type Output = Self;
fn add(self, other: Self) -> Self::Output {
Self {
x: self.x + other.x,
y: self.y + other.y,
}
}
}
Полный код на игровой площадке.
Но на самом деле лучше сузить каждую черту, связанную с минимальным:
// No trait bound on T: Vec2 can store any type
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Vec2<T> {
pub x: T,
pub y: T,
}
impl<T> Vec2<T> {
pub fn new(x: T, y: T) -> Vec2<T> {
Vec2 { x, y }
}
}
// Implement `+` operator for Vec2<T> only if T has it
impl<T> Add for Vec2<T>
where T: Add<T, Output = T>
{
type Output = Self;
fn add(self, other: Self) -> Self::Output {
Self {
x: self.x + other.x,
y: self.y + other.y,
}
}
}
// Implement `-` operator for Vec2<T> only if T has it
impl<T> Sub for Vec2<T>
where T: Sub<T, Output = T>
{
type Output = Self;
fn sub(self, other: Self) -> Self::Output {
Self {
x: self.x - other.x,
y: self.y - other.y,
}
}
}
Полный код на игровой площадке.
Таким образом, Vec2 может быть построен с любым возможным типом, но Add
реализуется, только если T
имеет соответствующий Add
; то же самое для Sub
.