rust 应为结构“Vec3d”,但在实现自定义结构的穆尔特性时找到类型参数“u32

30byixjq  于 2023-02-19  发布在  其他
关注(0)|答案(1)|浏览(142)

我正在尝试为Vec3d结构实现Mul特性。我希望mul函数将Vec3d的每个元素乘以一个数字并返回一个Vec3d。但是我遇到了这个错误

error[E0053]: method `mul` has an incompatible type for trait
  --> src\vec_3d.rs:26:21
   |
23 | impl<u32> Mul for Vec3d<u32> {
   |      --- this type parameter
...
26 |     fn mul(self, t: u32) -> Self::Output {
   |                     ^^^
   |                     |
   |                     expected struct `Vec3d`, found type parameter `u32`
   |                     help: change the parameter type to match the trait: `Vec3d<u32>`
   |
   = note: expected fn pointer `fn(Vec3d<_>, Vec3d<u32>) -> Vec3d<_>`
              found fn pointer `fn(Vec3d<_>, u32) -> Vec3d<_>`

我的代码如下所示
x一个一个一个一个x一个一个二个x
我最初使用泛型类型参数T

impl<T: Mul<Output = T>> Mul for Vec3d<T> {
    type Output = Self;

    fn mul(self, t: T) -> Self::Output {
        Self {
            x: self.x * t,
            y: self.x * t,
            z: self.x * t,
        }
    }
}

我在一些例子和其他问题中看到过同样的方法。有什么想法吗?我如何才能正确地实现这一点?

fhg3lkii

fhg3lkii1#

这与Mul文档中的示例几乎相同:向量乘标量,如线性代数中
Mul有一个默认的泛型,你可以在trait定义中看到:

pub trait Mul<Rhs = Self> {

这样做很方便,因为大多数Mul的实现者都将对Self进行乘法运算,而你却不是,所以你需要指定泛型:

impl Mul<u32> for Vec3d<u32> {
    type Output = Self;

    fn mul(self, t: u32) -> Self::Output {
        Self {
            x: self.x * t,
            y: self.y * t,
            z: self.z * t,
        }
    }
}

要使其完全通用,您可以尝试以下操作:

impl<T: Mul<Output = T>> Mul<T> for Vec3d<T>

但是,由于您要使用一个T 3次,因此需要将其限制为CloneCopy。通常的解决方法是为引用实现Mul

impl<'a, T> Mul<&'a T> for Vec3d<T>
where
    T: Mul<&'a T, Output = T>,
{
    type Output = Self;

    fn mul(self, t: &'a T) -> Self::Output {
        Self {
            x: self.x * t,
            y: self.y * t,
            z: self.z * t,
        }
    }
}

那么当类型实现Copy时,您可能需要一个非引用版本:

impl<T> Mul<T> for Vec3d<T>
where
    T: Mul<Output = T> + Copy,
{
    type Output = Self;

    fn mul(self, t: T) -> Self::Output {
        Self {
            x: self.x * t,
            y: self.y * t,
            z: self.z * t,
        }
    }
}

但更好的是,您可以在一个impl中同时完成这两项操作:

impl<T, R> Mul<R> for Vec3d<T>
where
    R: Copy,
    T: Mul<R, Output = T>,
{
    type Output = Self;

    fn mul(self, t: R) -> Self::Output {
        Self {
            x: self.x * t,
            y: self.y * t,
            z: self.z * t,
        }
    }
}

R&T时,将覆盖第一个实施例;当RTCopy时,将覆盖第二个实施例。&引用始终为Copy
另一件常见的事情是为每个整数类型实现Mul,这允许您对实现进行更多的控制,例如,如果您想为特定大小的整数优化它们。

相关问题