一、源碼
這段代碼實現了一個類型級別的長度計算系統,用于在編譯時計算數組長度和二進制數的位數。
- 定義(type_operators.rs)
/// A **type operator** that gives the length of an `Array` or the number of bits in a `UInt`.
#[allow(clippy::len_without_is_empty)]
pub trait Len {/// The length as a type-level unsigned integer.type Output: crate::Unsigned;/// This function isn't used in this crate, but may be useful for others.fn len(&self) -> Self::Output;
}
- 別名(operator_aliases.rs)
/// Alias for the associated type of `Len`: `Length<A> = <A as Len>::Output`
pub type Length<T> = <T as Len>::Output;
- 無符號整數實現(uint.rs)
// ---------------------------------------------------------------------------------------
// Getting length of unsigned integers, which is defined as the number of bits before `UTerm`/// Length of `UTerm` by itself is 0
impl Len for UTerm {type Output = U0;#[inline]fn len(&self) -> Self::Output {UTerm}
}/// Length of a bit is 1
impl<U: Unsigned, B: Bit> Len for UInt<U, B>
whereU: Len,Length<U>: Add<B1>,Add1<Length<U>>: Unsigned,
{type Output = Add1<Length<U>>;#[inline]fn len(&self) -> Self::Output {self.msb.len() + B1}
}
- 數組實現(array.rs)
// Length/// Length of `ATerm` by itself is 0
impl Len for ATerm {type Output = U0;#[inline]fn len(&self) -> Self::Output {UTerm}
}/// Size of a `TypeArray`
impl<V, A> Len for TArr<V, A>
whereA: Len,Length<A>: Add<B1>,Sum<Length<A>, B1>: Unsigned,
{type Output = Add1<Length<A>>;#[inline]fn len(&self) -> Self::Output {self.rest.len() + B1}
}
二、Len Trait 定義
pub trait Len {type Output: crate::Unsigned; // 輸出類型必須是Unsignedfn len(&self) -> Self::Output; // 運行時獲取長度的方法
}
-
類型級操作符: 在編譯時計算長度
-
Output: 關聯類型,表示長度的類型(必須是Unsigned類型)
-
len(): 運行時方法,實際返回類型級別的長度值
三、類型別名
pub type Length<T> = <T as Len>::Output;
-
簡化訪問: 提供更簡潔的方式來獲取類型的長度類型
-
用法: Length 等價于 ::Output
四、無符號整數實現(計算二進制位數)
- UTerm(終止符)的實現
impl Len for UTerm {type Output = U0; // 長度為0fn len(&self) -> Self::Output {UTerm // 返回UTerm(即U0)}
}
-
基準情況: 終止符的長度為0
-
UTerm 表示二進制數的結束,沒有位數
- UInt(二進制位)的實現
impl<U: Unsigned, B: Bit> Len for UInt<U, B>
whereU: Len, // 剩余部分必須有長度Length<U>: Add<B1>, // 剩余長度+1必須可計算Add1<Length<U>>: Unsigned, // 結果必須是Unsigned類型
{type Output = Add1<Length<U>>; // 長度 = 剩余長度 + 1fn len(&self) -> Self::Output {self.msb.len() + B1 // 遞歸計算}
}
-
遞歸計算: 當前UInt的長度 = 剩余部分長度 + 1
-
self.msb: 剩余的高位部分
-
B1: 類型級別的數字1
-
Add1<Length>: 類型級別的加法 Length + 1
示例: 計算 UInt<UInt<UTerm, B1>, B0> (二進制10,即數字2) 的長度:
-
第一層:UInt<UInt<UTerm, B1>, B0> → Length<UInt<UTerm, B1>> + 1
-
第二層:UInt<UTerm, B1> → Length + 1 = 0 + 1 = 1
-
結果:1 + 1 = 2 位
五、數組實現(計算元素個數)
- ATerm(數組終止符)的實現
impl Len for ATerm {type Output = U0; // 長度為0fn len(&self) -> Self::Output {UTerm}
}
-
基準情況: 空數組的長度為0
-
ATerm 表示數組的結束
- TArr(類型數組)的實現
impl<V, A> Len for TArr<V, A>
whereA: Len, // 剩余數組必須有長度Length<A>: Add<B1>, // 剩余長度+1必須可計算Sum<Length<A>, B1>: Unsigned, // 結果必須是Unsigned類型
{type Output = Add1<Length<A>>; // 長度 = 剩余數組長度 + 1fn len(&self) -> Self::Output {self.rest.len() + B1 // 遞歸計算}
}
-
遞歸計算: 當前數組長度 = 剩余數組長度 + 1
-
self.rest: 數組中剩余的元素
-
示例: 數組 [i32, f64, bool] 的長度計算:
-
第一層:TArr<i32, TArr<f64, TArr<bool, ATerm>>> → Length<TArr<f64, TArr<bool, ATerm>>> + 1
-
第二層:TArr<f64, TArr<bool, ATerm>> → Length<TArr<bool, ATerm>> + 1
-
第三層:TArr<bool, ATerm> → Length + 1 = 0 + 1 = 1
-
結果:1 + 1 + 1 = 3 個元素
-
六、設計特點
-
類型安全: 所有計算在編譯時完成,保證類型正確性
-
遞歸模式: 使用遞歸遍歷數據結構
-
統一接口: 數組和二進制數使用相同的Len trait
-
零成本抽象: 運行時沒有額外開銷,所有信息在編譯時已知
這種模式常用于需要編譯時計算的場景,如靜態數組邊界檢查、類型級別的數學運算等。