一、源码
这段代码实现了一个类型级别的长度计算系统,用于在编译时计算数组长度和二进制数的位数。
- 定义(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
-
零成本抽象: 运行时没有额外开销,所有信息在编译时已知
这种模式常用于需要编译时计算的场景,如静态数组边界检查、类型级别的数学运算等。