I have the following toy code which makes use of generics to implement some operations on a 3d vector as a struct of 3 generic elements.
use std::ops::Add;
use std::ops::Mul;
#[derive(Debug)]
pub struct Vec3<T> {
x: T,
y: T,
z: T,
}
impl<T> Vec3<T> {
pub fn new(x: T, y: T, z: T) -> Vec3<T> {
Vec3 { x, y, z }
}
}
impl<T: Add<Output = T> + Copy> Add<T> for &Vec3<T> {
type Output = Vec3<T>;
fn add(self, other: T) -> Vec3<T> {
Vec3 {
x: self.x + other,
y: self.y + other,
z: self.z + other,
}
}
}
impl<T: Add<Output = T> + Copy> Add<&Vec3<T>> for &Vec3<T> {
type Output = Vec3<T>;
fn add(self, other: &Vec3<T>) -> Vec3<T> {
Vec3 {
x: self.x + other.x,
y: self.y + other.y,
z: self.z + other.z,
}
}
}
impl<T: Mul<Output = T> + Copy> Mul<T> for &Vec3<T> {
type Output = Vec3<T>;
fn mul(self, other: T) -> Vec3<T> {
Vec3 {
x: self.x * other,
y: self.y * other,
z: self.z * other,
}
}
}
impl<T: Mul<Output = T> + Copy> Mul<&Vec3<T>> for &Vec3<T> {
type Output = Vec3<T>;
fn mul(self, other: &Vec3<T>) -> Vec3<T> {
Vec3 {
x: self.x * other.x,
y: self.y * other.y,
z: self.z * other.z,
}
}
}
It's pretty plain to see that all I did was copy and paste my impl Add
's and replace Add
for Mul
and renamed the method names.
This slight repetition brings me to my question - Is there something in rust which generalizes this as well? That is something akin to a generic trait or perhaps "meta trait". In my scenario, a relevant "meta trait" Op
would have some method op
. Then, instead of implementing Add
and Mul
, one would implement Op
and op
would take the place of the +
and *
operators respectively.
I explored and found supertraits but I cannot imagine how they could be used as I hope beyond what I imagine would be the basic step:
trait Op<T>:Add<T>+Mul<T>{
fn op(&self)->T;
}
Regarding your question for a more general trait for binary operations that will create impls of Add, Mul etc. for you: There is none as far as I'm aware, and I think you cannot define it yourself because of orphan rules. You could:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.