Rust DRY特性和泛型-impl Add和Mul几乎相同

问题描述 投票:0回答:1

我有以下玩具代码,该代码利用泛型对3d向量作为3个泛型元素的结构实施一些操作。

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,
        }
    }
}

很明显,我所做的就是复制并粘贴我的impl Add,然后将Add替换为Mul,并重命名了方法名称。

这种轻微的重复使我想到我的问题-是否也有锈蚀的东西使这一点普遍化?这类似于一般特征或“元特征”。在我的场景中,相关的“元特征” Op将具有某种方法op。然后,代替实现AddMul,将实现Opop分别代替+*运算符。

我探索并发现了特征,但是我无法想象如何使用它们,因为我希望超出我想象的基本步骤:

trait Op<T>:Add<T>+Mul<T>{
    fn op(&self)->T;
}
generics rust traits generic-programming
1个回答
2
投票

关于二进制操作的更一般特征的问题,它将为您创建Add,Mul等的隐喻:据我所知,目前还没有,我认为由于孤立规则,您不能define it yourself。您可以:

  • 为二进制操作特征写macro
  • [使用现有的Vector3,例如nalgebra,它已经为您实现了这些特征
  • 尝试将num_derive推广到具有多个成员的结构上>]
© www.soinside.com 2019 - 2024. All rights reserved.