给定以下结构:
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/