ano*_*_13 19 operator-overloading rust
给定以下结构:
struct Vector3D {
x: f32,
y: f32,
z: f32
}
Run Code Online (Sandbox Code Playgroud)
*
当右边是a时Vector3D
,我想重载它的运算符来做一个点积,当RHS是a时,我想重做元素乘法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
}
}
Run Code Online (Sandbox Code Playgroud)
编译器说第一个impl块:
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 {
...
Run Code Online (Sandbox Code Playgroud)
反之亦然,其他实施.
She*_*ter 29
从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);
}
Run Code Online (Sandbox Code Playgroud)
允许这种情况的重大变化是引入了相关类型,这些类型type Output =
在每个实现中都显示为位.另一个值得注意的变化是,运算符traits现在按值使用参数,消耗它们,所以我继续Copy
为结构实现.
huo*_*uon 12
目前,impl
每个特征类型对只允许一个.
这种情况将得到改善与RFC 48,但它不是完整的故事(它不是真正的故事的话).相关部分是Coherence,它当然没有特别提到运营商重载案例,并且基本上说它仍然是非法的:
以下示例不正常:
Run Code Online (Sandbox Code Playgroud)trait Iterator<E> { ... } impl Iterator<char> for ~str { ... } impl Iterator<u8> for ~str { ... }
Niko Matsakis(RFC和Rust类型系统专家的作者)一直在考虑这些超载特征:他是发表的人("如果我想要超载?")下面的诀窍,但他表达了他的厌恶对此,提到他希望允许你编写的实现......
...这是他的RFC 135的用武之地."multidispatch traits"中详细描述了这种情况.
您现在可以使用辅助特征来解决它.额外的特征层允许您只编写一个特征,impl Mul<...> for Vector3D
但代价是需要为您希望具有多个实现的每种类型的新特征Mul
.
#[deriving(Show)]
struct Vector3D {
x: f32,
y: f32,
z: f32
}
trait MulVec3D<Res> {
fn do_mul(&self, v: &Vector3D) -> Res;
}
// Multiplication with scalar
impl MulVec3D<Vector3D> for f32 {
fn do_mul(&self, v: &Vector3D) -> Vector3D {
Vector3D {x: v.x * *self, y: v.y * *self, z: v.z * *self}
}
}
// Multiplication with vector, aka dot product
impl MulVec3D<f32> for Vector3D {
fn do_mul(&self, v: &Vector3D) -> f32 {
self.x * v.x + self.y * v.y + self.z * v.z
}
}
impl<Res, RHS: MulVec3D<Res>> Mul<RHS, Res> for Vector3D {
fn mul(&self, rhs: &RHS) -> Res {
rhs.do_mul(self)
}
}
fn main() {
let a = Vector3D { x: 1.0, y: 2.0, z: 3.0 };
let b = Vector3D { x: -3.0, y: 2.0, z: -1.0 };
println!("{}, {}", a * 2f32, a * b); // Vector3D { x: 2, y: 4, z: 6 }, -2
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3421 次 |
最近记录: |