【PhysUnits】13 减法操作(sub.rs)
一、源码
这段代码定义了一个自定义的减法 trait MySub 并为实现了特定约束的整数类型实现了这个 trait。
use super::basic::Integer;
use core::ops::{Neg, Sub, Add};pub trait MySub<Rhs = Self> {type Output;fn my_sub(self, rhs: Rhs) -> Self::Output;
}impl<I1: Integer, I2: Integer> MySub<I2> for I1
whereI1: Add<<I2 as Neg>::Output>,I2: Neg,
{type Output = <I1 as Add<<I2 as Neg>::Output>>::Output;#[inline]fn my_sub(self, rhs: I2) -> Self::Output {self + (-rhs)}
}
二、导入部分
use super::basic::Integer;
use core::ops::{Neg, Sub, Add};
-
从父模块的 basic 子模块导入 Integer trait
-
从核心库导入 Neg(取负)、Sub(减法) 和 Add(加法) 这三个操作 trait
三、自定义减法 trait 定义
pub trait MySub<Rhs = Self> {type Output;fn my_sub(self, rhs: Rhs) -> Self::Output;
}
`
+ 定义了一个名为 MySub 的公共 trait+ 使用泛型参数 Rhs (Right Hand Side 的缩写),默认值为 Self (即实现该 trait 的类型自身)+ 声明了一个关联类型 Output 表示运算结果的类型+ 定义了一个方法 my_sub,接收自身和右操作数,返回 Output 类型的结果### 四、trait 实现
```rust
impl<I1: Integer, I2: Integer> MySub<I2> for I1
whereI1: Add<<I2 as Neg>::Output>,I2: Neg,
{type Output = <I1 as Add<<I2 as Neg>::Output>>::Output;#[inline]fn my_sub(self, rhs: I2) -> Self::Output {self + (-rhs)}
}
-
为所有实现了 Integer 的类型 I1 和 I2 实现 MySub
-
where 子句约束:
-
I1 必须能加上 I2 的负值 (I1: Add<::Output>)
-
I2 必须能取负 (I2: Neg)
-
-
关联类型 Output 定义为 I1 加 I2 的负值的结果类型
-
my_sub 方法实现为 self + (-rhs),即通过加负来实现减
-
#[inline] 提示编译器考虑内联此方法以提高性能
五、关键点解析
- 数学原理:
-
这段代码实现了减法作为加负数的操作 (a - b = a + (-b))
-
这是数学上减法的标准定义方式
- 类型系统:
-
使用了复杂的类型约束确保类型安全
-
I2 as Neg>::Output 获取 I2 取负后的类型
-
I1 as Add<…>::Output 获取 I1 与某类型相加的结果类型
- 设计考虑:
-
自定义 MySub trait 是为了绕过 Rust 的孤儿规则
-
保持了与标准库 Sub trait 相似的接口设计
六、使用示例
假设有以下类型:
struct MyInt(i32);impl Integer for MyInt {...}
impl Neg for MyInt {type Output = MyInt;fn neg(self) -> Self::Output {...}
}
impl Add for MyInt {type Output = MyInt;fn add(self, rhs: Self) -> Self::Output {...}
}
可以这样使用:
let a = MyInt(5);
let b = MyInt(3);
let c = a.my_sub(b); // 相当于 5 - 3
七、与标准库 Sub 的区别
-
避免了孤儿规则问题,因为 MySub 是本地的
-
方法名改为 my_sub 而非 sub
-
其他方面保持了与标准库 Sub 相同的设计理念
这种模式在需要扩展外部类型功能时很常见,特别是在无法直接实现外部 crate 的 trait 时。