前文曾经叙述的常量类(Const)包含了本程序的功能,但它目前必须在夜版rust下编译。考虑2D CAD使用需要相对简单,过渡期采用本程序。待rust稳定版可以实现常量类或有3D需求时改用常量类。
源码
//algebraic_units.rs 代数单位元
use std::ops::{Add, Mul, Neg};/// 零元素 (加法单位元)
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct Zero;/// 单位元 (乘法单位元)
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct One;/// 负单位元 (乘法逆元)
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct DecOne;// ========== Zero 的实现 ==========// Zero + T = T
impl<T> Add<T> for Zero {type Output = T;fn add(self, rhs: T) -> T {rhs}
}// Zero * Zero = Zero
impl Mul for Zero {type Output = Zero;fn mul(self, _: Self) -> Self {Zero}
}// Zero * T = Zero
impl<T> Mul<T> for Zero {type Output = Zero;fn mul(self, _: T) -> Self {Zero}
}// T * Zero = Zero
impl<T> Mul<Zero> for T {type Output = Zero;fn mul(self, _: Zero) -> Zero {Zero}
}// ========== One 的实现 ==========// One * One = One
impl Mul for One {type Output = One;fn mul(self, _: Self) -> Self {One}
}// One * T = T
impl<T> Mul<T> for One {type Output = T;fn mul(self, rhs: T) -> T {rhs}
}// T * One = T
impl<T> Mul<One> for T {type Output = T;fn mul(self, _: One) -> T {self}
}// One + T = T + 1 (需要 T 支持 Add<i32>)
impl<T: Add<i32, Output = T>> Add<T> for One {type Output = T;fn add(self, rhs: T) -> T {rhs + 1}
}// ========== DecOne 的实现 ==========// DecOne * DecOne = One
impl Mul for DecOne {type Output = One;fn mul(self, _: Self) -> One {One}
}// DecOne * T = -T (需要 T 支持 Neg)
impl<T: Neg<Output = T>> Mul<T> for DecOne {type Output = T;fn mul(self, rhs: T) -> T {-rhs}
}// T * DecOne = -T (需要 T 支持 Neg)
impl<T: Neg<Output = T>> Mul<DecOne> for T {type Output = T;fn mul(self, _: DecOne) -> T {-self}
}// DecOne + T = T - 1 (需要 T 支持 Sub<i32>)
impl<T: Sub<i32, Output = T>> Add<T> for DecOne {type Output = T;fn add(self, rhs: T) -> T {rhs - 1}
}// ========== 其他组合运算 ==========// One * DecOne = DecOne
impl Mul<DecOne> for One {type Output = DecOne;fn mul(self, rhs: DecOne) -> DecOne {rhs}
}// DecOne * One = DecOne
impl Mul<One> for DecOne {type Output = DecOne;fn mul(self, _: One) -> DecOne {self}
}// Zero * DecOne = Zero (已由 Zero 的通用实现覆盖)
// DecOne * Zero = Zero (已由 Zero 的通用实现覆盖)#[cfg(test)]
mod tests {use super::*;#[test]fn test_zero_operations() {let z = Zero;// 加法测试assert_eq!(z + 5, 5); // 0 + 5 = 5assert_eq!(z + (-3), -3); // 0 + (-3) = -3assert_eq!(z + "hello", "hello"); // 0 + 非数字类型// 乘法测试assert_eq!(z * z, z); // 0 * 0 = 0assert_eq!(z * 10, z); // 0 * 10 = 0assert_eq!(10 * z, z); // 10 * 0 = 0assert_eq!(z * One, z); // 0 * 1 = 0assert_eq!(One * z, z); // 1 * 0 = 0assert_eq!(z * DecOne, z); // 0 * -1 = 0assert_eq!(DecOne * z, z); // -1 * 0 = 0}#[test]fn test_one_operations() {let o = One;// 乘法测试assert_eq!(o * o, o); // 1 * 1 = 1assert_eq!(o * 7, 7); // 1 * 7 = 7assert_eq!(7 * o, 7); // 7 * 1 = 7assert_eq!(o * DecOne, DecOne); // 1 * -1 = -1assert_eq!(DecOne * o, DecOne); // -1 * 1 = -1// 加法测试assert_eq!(o + 3, 4); // 1 + 3 = 4assert_eq!(o + (-2), -1); // 1 + (-2) = -1}#[test]fn test_dec_one_operations() {let d = DecOne;// 乘法测试assert_eq!(d * d, One); // -1 * -1 = 1assert_eq!(d * 4, -4); // -1 * 4 = -4assert_eq!(4 * d, -4); // 4 * -1 = -4assert_eq!(d * One, d); // -1 * 1 = -1assert_eq!(One * d, d); // 1 * -1 = -1// 加法测试assert_eq!(d + 5, 4); // -1 + 5 = 4assert_eq!(d + (-3), -4); // -1 + (-3) = -4}#[test]fn test_mixed_operations() {// 混合类型运算assert_eq!(One * (DecOne * 3), -3); // 1 * (-1 * 3) = -3assert_eq!((Zero + One) * DecOne, DecOne); // (0 + 1) * -1 = -1assert_eq!(DecOne * (One + 1), -2); // -1 * (1 + 1) = -2}#[test]fn test_commutative_law() {// 验证交换律let a = 5;assert_eq!(a * One, One * a);assert_eq!(a * DecOne, DecOne * a);assert_eq!(a * Zero, Zero * a);}#[test]fn test_associative_law() {// 验证结合律 (注意:加法实现不满足严格结合律)assert_eq!((One * DecOne) * DecOne, One * (DecOne * DecOne)); // (-1) * -1 = 1}#[test]fn test_distributive_law() {// 验证分配律 (a + b) * c = a*c + b*clet a = 2;let b = 3;let c = DecOne;assert_eq!((a + b) * c, a * c + b * c); // 5 * -1 = -2 + -3}
}
代码分析
这段代码定义了几个表示数学概念的单元类型(Zero、One、DecOne)并实现了它们的运算规则。下面将详细解释:
- 类型定义
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct Zero; // 表示加法单位元(0)
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct One; // 表示乘法单位元(1)
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct DecOne; // 表示乘法逆元(-1)
- Zero 的实现
实现了加法单位元的性质:
-
Zero + T = T:任何数加0等于它本身
-
Zero * T = Zero:任何数乘0等于0
-
T * Zero = Zero:乘法交换律
- One 的实现
实现了乘法单位元的性质:
-
One * T = T:任何数乘1等于它本身
-
T * One = T:乘法交换律
-
One + T = T + 1:特殊的加法实现(需要T支持加整数)
- DecOne 的实现
实现了乘法逆元的性质:
-
DecOne * DecOne = One:-1 * -1 = 1
-
DecOne * T = -T:任何数乘-1等于它的负数
-
T * DecOne = -T:乘法交换律
-
DecOne + T = T - 1:特殊的加法实现(需要T支持减整数)
- 其他组合运算
处理了这些类型之间的交互运算,如:
-
One * DecOne = DecOne
-
DecOne * One = DecOne
- 测试部分
包含详尽的测试用例验证:
-
基本运算的正确性
-
混合运算的正确性
-
数学定律(交换律、结合律、分配律)的验证
关键点
-
这些类型都是零大小的单元类型,仅用作标记
-
通过Rust的trait系统实现了运算符重载
-
实现了数学中单位元的抽象概念:
-
Zero是加法的单位元
-
One是乘法的单位元
-
DecOne是乘法的逆元
- 泛型实现使得这些运算可以适用于多种类型
这种实现方式在代数系统、线性代数库或符号计算中很有用,可以优雅地表示数学概念而不引入运行时开销。