operator-overloading - 如何为不同的 RHS 类型和返回值重载运算符?

标签 operator-overloading rust

给定以下结构:

struct Vector3D {
    x: f32,
    y: f32,
    z: f32
}

我想重载它的 * 运算符,当右侧是 Vector3D 时做点积,当 RHS 是时做逐元素乘法一个 f32。我的代码如下所示:

// Multiplication with scalar
impl Mul<f32, Vector3D> for Vector3D {
    fn mul(&self, f: &f32) -> Vector3D {
        Vector3D {x: self.x * *f, y: self.y * *f, z: self.z * *f} 
    }   
}
// Multiplication with vector, aka dot product
impl Mul<Vector3D, f32> for Vector3D {
    fn mul(&self, other: &Vector3D) -> f32 {
        self.x * other.x + self.y * other.y + self.z * other.z
    }   
}

编译器对第一个 impl block 说:

Vector3D.rs:40:1: 44:2 error: conflicting implementations for trait `std::ops::Mul`
Vector3D.rs:40 impl Mul<f32, Vector3D> for Vector3D { 
...
Vector3D.rs:53:1: 57:2 note: note conflicting implementation here
Vector3D.rs:53 impl Mul<Vector3D, f32> for Vector3D { 
...

对于其他实现,反之亦然。

最佳答案

从 Rust 1.0 开始,您现在可以实现这个:

use std::ops::Mul;

#[derive(Copy, Clone, PartialEq, Debug)]
struct Vector3D {
    x: f32,
    y: f32,
    z: f32,
}

// Multiplication with scalar
impl Mul<f32> for Vector3D {
    type Output = Vector3D;

    fn mul(self, f: f32) -> Vector3D {
        Vector3D {
            x: self.x * f,
            y: self.y * f,
            z: self.z * f,
        }
    }
}

// Multiplication with vector, aka dot product
impl Mul<Vector3D> for Vector3D {
    type Output = f32;

    fn mul(self, other: Vector3D) -> f32 {
        self.x * other.x + self.y * other.y + self.z * other.z
    }
}

fn main() {
    let a = Vector3D {
        x: 1.0,
        y: 2.0,
        z: 3.0,
    };
    let b = a * -1.0;
    let c = a * b;

    println!("{:?}", a);
    println!("{:?}", b);
    println!("{:?}", c);
}

允许这样做的重大变化是引入了关联类型,它在每个实现中显示为 type Output = 位。另一个值得注意的变化是运算符特征现在按值获取参数,使用它们,所以我继续为结构实现 Copy

关于operator-overloading - 如何为不同的 RHS 类型和返回值重载运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24594374/

相关文章:

c++ - 为什么标准容器迭代器不重载 `->*` ?

rust 柴油有条件地过滤一个查询

rust - 当 Rust FFI 函数返回一个没有#[repr(C)] 的结构给 C 时返回什么?

c++ - 迭代器和重载 << 运算符

c++ - 如何重载运算符 += 以添加两个类对象

c++ - 我可以用不同的返回类型重载 'operator new' 吗?

rust - 在Hyper Body结构上附加换行符

enums - 两种类型的派送应该怎么做?

rust - 如何将 Arc 克隆传递给闭包?

c++ - operator<< 重载调用打印函数麻烦