在实现基本的固定大小向量类型(例如float2
)时,我希望支持Add
和Sub
个特征.稍后,我会支持Mul
和*Assign
.
通过查阅文档和其他示例,我得出以下结论:
use std::ops::{Add, Sub};
#[derive(Copy, Clone)]
struct float2(f64, f64);
impl Add for float2 {
type Output = float2;
fn add(self, _rhs: float2) -> float2 {
float2(self.0 + _rhs.0, self.1 + _rhs.1)
}
}
impl Sub for float2 {
type Output = float2;
fn sub(self, _rhs: float2) -> float2 {
float2(self.0 - _rhs.0, self.1 - _rhs.1)
}
}
这适用于基本示例,但我发现在实践中,我经常会以作为参数传入的引用以及堆栈上的本地float2
结尾.
要混合这些,我需要:
- 取消引用变量(可以,但会降低代码的可读性).
- 声明运算符重载引用的组合.
例子:
impl<'a, 'b> Add<&'b float2> for &'a float2 {
type Output = float2;
fn add(self, _rhs: &'b float2) -> float2 {
float2(self.0 + _rhs.0, self.1 + _rhs.1)
}
}
impl<'a> Add<float2> for &'a float2 {
type Output = float2;
fn add(self, _rhs: float2) -> float2 {
float2(self.0 + _rhs.0, self.1 + _rhs.1)
}
}
impl<'b> Add<&'b float2> for float2 {
type Output = float2;
fn add(self, _rhs: &'b float2) -> float2 {
float2(self.0 + _rhs.0, self.1 + _rhs.1)
}
}
/*... and again for Sub */
而这允许在不取消引用的情况下编写表达式.列举每种组合会变得相当乏味,尤其是在添加更多操作时&;类型(float3
float4
…).
有没有一种被普遍接受的方法...
- 为运算符重载自动强制类型?
- 使用宏或语言的其他功能来避免冗长的重复?
还是希望开发者:
- 根据需要显式访问变量作为引用.
- 根据需要显式取消引用变量.
- 编写大量重复的运算符重载函数.
Note, I'm currently a beginner, I've checked some quite advanced math libraries in Rust, they're way over my head, while I could use them - I would like to understand how to write operator overloading for my own types.