一、源碼
代碼實現了一個在類型級別計算最大公約數(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系統和關聯類型來實現復雜的數學運算。