一、源码
代码实现了一个在类型级别计算最大公约数(GCD)的系统
- 定义(type_operators.rs)
/// A **type operator** that computes the [greatest common divisor][gcd] of `Self` and `Rhs`.
///
/// [gcd]: https://en.wikipedia.org/wiki/Greatest_common_divisor
///
/// # Example
///
/// ```rust
/// use unitrix::number::{Gcd, Unsigned, types::{U12, U8}};
///
/// assert_eq!(<U12 as Gcd<U8>>::Output::to_i32(), 4);
/// ```
pub trait Gcd<Rhs> {/// The greatest common divisor.type Output;
}
- 别名(operator_aliases.rs)
/// Alias for the associated type of `Gcd`: `Gcf<A, B> = <A as Gcd<B>>::Output>`
pub type Gcf<A, B> = <A as Gcd<B>>::Output;
- 无符号数实现(uint.rs)
/// gcd(0, 0) = 0
impl Gcd<U0> for U0 {type Output = U0;
}/// gcd(x, 0) = x
impl<X> Gcd<U0> for X
whereX: Unsigned + NonZero,
{type Output = X;
}/// gcd(0, y) = y
impl<Y> Gcd<Y> for U0
whereY: Unsigned + NonZero,
{type Output = Y;
}/// gcd(x, y) = 2*gcd(x/2, y/2) if both x and y even
impl<Xp, Yp> Gcd<Even<Yp>> for Even<Xp>
whereXp: Gcd<Yp>,Even<Xp>: NonZero,Even<Yp>: NonZero,
{type Output = UInt<Gcf<Xp, Yp>, B0>;
}/// gcd(x, y) = gcd(x, y/2) if x odd and y even
impl<Xp, Yp> Gcd<Even<Yp>> for Odd<Xp>
whereOdd<Xp>: Gcd<Yp>,Even<Yp>: NonZero,
{type Output = Gcf<Odd<Xp>, Yp>;
}/// gcd(x, y) = gcd(x/2, y) if x even and y odd
impl<Xp, Yp> Gcd<Odd<Yp>> for Even<Xp>
whereXp: Gcd<Odd<Yp>>,Even<Xp>: NonZero,
{type Output = Gcf<Xp, Odd<Yp>>;
}/// gcd(x, y) = gcd([max(x, y) - min(x, y)], min(x, y)) if both x and y odd
///
/// This will immediately invoke the case for x even and y odd because the difference of two odd
/// numbers is an even number.
impl<Xp, Yp> Gcd<Odd<Yp>> for Odd<Xp>
whereOdd<Xp>: Max<Odd<Yp>> + Min<Odd<Yp>>,Odd<Yp>: Max<Odd<Xp>> + Min<Odd<Xp>>,Maximum<Odd<Xp>, Odd<Yp>>: Sub<Minimum<Odd<Xp>, Odd<Yp>>>,Diff<Maximum<Odd<Xp>, Odd<Yp>>, Minimum<Odd<Xp>, Odd<Yp>>>: Gcd<Minimum<Odd<Xp>, Odd<Yp>>>,
{type Output =Gcf<Diff<Maximum<Odd<Xp>, Odd<Yp>>, Minimum<Odd<Xp>, Odd<Yp>>>, Minimum<Odd<Xp>, Odd<Yp>>>;
}#[cfg(test)]
mod gcd_tests {use super::*;use crate::consts::*;macro_rules! gcd_test {($( $a:ident, $b:ident => $c:ident ),* $(,)*) => {$(assert_eq!(<Gcf<$a, $b> as Unsigned>::to_usize(), $c::to_usize());assert_eq!(<Gcf<$b, $a> as Unsigned>::to_usize(), $c::to_usize());)*}}#[test]fn gcd() {gcd_test! {U0, U0 => U0,U0, U42 => U42,U12, U8 => U4,U13, U1013 => U1, // Two primesU9, U26 => U1, // Not prime but coprimeU143, U273 => U13,U117, U273 => U39,}}
}
4.有符号整数实现(int.rs)
// ---------------------------------------------------------------------------------------
// Gcd
use crate::{Gcd, Gcf};impl Gcd<Z0> for Z0 {type Output = Z0;
}impl<U> Gcd<PInt<U>> for Z0
whereU: Unsigned + NonZero,
{type Output = PInt<U>;
}impl<U> Gcd<Z0> for PInt<U>
whereU: Unsigned + NonZero,
{type Output = PInt<U>;
}impl<U> Gcd<NInt<U>> for Z0
whereU: Unsigned + NonZero,
{type Output = PInt<U>;
}impl<U> Gcd<Z0> for NInt<U>
whereU: Unsigned + NonZero,
{type Output = PInt<U>;
}impl<U1, U2> Gcd<PInt<U2>> for PInt<U1>
whereU1: Unsigned + NonZero + Gcd<U2>,U2: Unsigned + NonZero,Gcf<U1, U2>: Unsigned + NonZero,
{type Output = PInt<Gcf<U1, U2>>;
}impl<U1, U2> Gcd<PInt<U2>> for NInt<U1>
whereU1: Unsigned + NonZero + Gcd<U2>,U2: Unsigned + NonZero,Gcf<U1, U2>: Unsigned + NonZero,
{type Output = PInt<Gcf<U1, U2>>;
}impl<U1, U2> Gcd<NInt<U2>> for PInt<U1>
whereU1: Unsigned + NonZero + Gcd<U2>,U2: Unsigned + NonZero,Gcf<U1, U2>: Unsigned + NonZero,
{type Output = PInt<Gcf<U1, U2>>;
}impl<U1, U2> Gcd<NInt<U2>> for NInt<U1>
whereU1: Unsigned + NonZero + Gcd<U2>,U2: Unsigned + NonZero,Gcf<U1, U2>: Unsigned + NonZero,
{type Output = PInt<Gcf<U1, U2>>;
}
二、核心概念
这是一个类型级编程的实现,使用Rust的trait系统在编译时计算GCD,而不是运行时。所有计算都在类型系统层面完成。
三、源码解析
- 定义(type_operators.rs)
pub trait Gcd<Rhs> {type Output;
}
-
定义了一个泛型trait Gcd,其中Rhs是右操作数
-
有一个关联类型Output表示计算结果
-
这是一个类型运算符,不包含实际方法,只有类型关联
- 别名(operator_aliases.rs)
pub type Gcf<A, B> = <A as Gcd<B>>::Output;
-
创建了类型别名Gcf(Greatest Common Factor)
-
简化了访问GCD结果的语法:Gcf<A, B> 等价于 <A as Gcd>::Output
- 无符号数实现(uint.rs)
实现了欧几里得算法的类型级版本:
基本情况:
-
gcd(0, 0) = 0
-
gcd(x, 0) = x (x ≠ 0)
-
gcd(0, y) = y (y ≠ 0)
递归情况:
-
双偶数:gcd(x, y) = 2 * gcd(x/2, y/2)
-
x奇y偶:gcd(x, y) = gcd(x, y/2)
-
x偶y奇:gcd(x, y) = gcd(x/2, y)
-
双奇数:gcd(x, y) = gcd(|x-y|, min(x,y))(利用两奇数差为偶数的性质)
- 有符号整数实现(int.rs)
处理有符号整数的情况:
-
gcd(0, 0) = 0
-
gcd(0, ±y) = |y| (y ≠ 0)
-
gcd(±x, 0) = |x| (x ≠ 0)
-
gcd(±x, ±y) = gcd(|x|, |y|) - 结果总是正数
四、技术特点
- 类型级编程
-
所有计算在编译时完成
-
使用trait系统和关联类型表达计算
-
结果在类型系统中可用,无需运行时计算
- 递归实现
基于欧几里得算法,通过模式匹配(奇偶性)选择正确的计算路径
3. 零成本抽象
-
编译时计算,运行时无开销
-
类型安全:确保所有操作都在有效范围内
五、使用示例
// 编译时计算 gcd(12, 8) = 4
type Result = Gcf<U12, U8>;
assert_eq!(Result::to_i32(), 4); // 编译时已知结果为4
六、设计优势
-
编译时验证:类型系统确保计算正确性
-
零运行时开销:所有计算在编译期完成
-
类型安全:防止无效操作(如除以零)
-
模块化设计:清晰的trait层次和实现分离
这是一个典型的使用Rust类型系统进行编译时计算的例子,展示了如何利用trait系统和关联类型来实现复杂的数学运算。