【unitrix】 1.8 常量约束(const_traits.rs)
一、源码
这段代码是用Rust实现的类型级数字系统,使用类型来表示整数并定义它们的属性。这是一种在编译时进行数学运算的技术,常用于需要编译时验证的场景。
use crate::sealed::Sealed;
use crate::number::{Z0, P1, N1, B0, B1};// ========== Marker Traits Definition ==========
// ========== 标记特质定义 ==========/// Integer type marker trait
/// 整数类型标记特质
pub trait Integer: Default+ Sealed + Copy + 'static {/// Convert to i32 (will be deprecated after Var implementation)/// 转换为i32 (Var方法完善后将取消)fn to_i32() -> i32;
}/// Non-zero integer marker
/// 非零整数标记
pub trait NonZero: Integer {}// Integer not equal to 1
/// 不等于1的整数标记
pub trait NonOne: Integer {}/// Integer not equal to -1
/// 不等于-1的整数标记
pub trait NonNegOne: Integer {}// Unsigned integer marker
/// 无符号整数标记
pub trait Unsigned: Integer {}// ========== NonZero Implementations ==========
// ========== NonZero 实现 ==========
impl NonZero for P1 {}
impl NonZero for N1 {}
impl<H: NonZero> NonZero for B0<H> {}
impl<H: NonZero> NonZero for B1<H> {}// ========== Integer Implementations ==========
// ========== Integer 实现 ==========// Z0 represents 0
// Z0 表示 0
impl Integer for Z0 {#[inline(always)]fn to_i32() -> i32 {0}
}// P1 represents +1
// P1 表示 +1
impl Integer for P1 {#[inline(always)]fn to_i32() -> i32 {1}
}// N1 represents -1
// N1 表示 -1
impl Integer for N1 {#[inline(always)]fn to_i32() -> i32 {-1}
}// B0<H> represents H * 2
// B0<H> 表示 H * 2
impl<H: NonZero> Integer for B0<H> {#[inline(always)]fn to_i32() -> i32 {H::to_i32() * 2}
}// B1<H> represents H * 2 + 1
// B1<H> 表示 H * 2 + 1
impl<H: NonZero> Integer for B1<H> {#[inline(always)]fn to_i32() -> i32 {H::to_i32() * 2 + 1}
}// ========== NonOne Implementations ==========
// ========== NonOne 实现 ==========
impl NonOne for Z0 {}
impl NonOne for N1 {}
impl<H: NonZero> NonOne for B0<H> {}
impl<H: NonZero> NonOne for B1<H> {}// ========== NonNegOne Implementations ==========
// ========== NonNegOne 实现 ==========
impl NonNegOne for Z0 {}
impl NonNegOne for P1 {}
impl<H: NonZero> NonNegOne for B0<H> {}
impl<H: NonZero> NonNegOne for B1<H> {}// ========== Unsigned Implementations ==========
// ========== Unsigned 实现 ==========
impl Unsigned for Z0 {}
impl Unsigned for P1 {}
impl<H: NonZero + NonNegOne> Unsigned for B0<H> {}
impl<H: NonZero + NonNegOne> Unsigned for B1<H> {}
二、代码分析
- 基本结构
use crate::sealed::Sealed;
use crate::number::{Z0, P1, N1, B0, B1};
- 引入了密封模式(Sealed)和一些数字类型(Z0, P1, N1, B0, B1)
- 标记特质(Trait)定义
定义了一系列标记特质来描述数字类型的属性:
-
Integer: 基础整数特质,要求实现Default、Sealed、Copy和’static,并提供一个to_i32()方法
-
NonZero: 标记非零整数
-
NonOne: 标记不等于1的整数
-
NonNegOne: 标记不等于-1的整数
-
Unsigned: 标记无符号整数(非负整数)
- 数字类型表示
系统使用类型来表示数字:
-
Z0: 表示数字0
-
P1: 表示+1
-
N1: 表示-1
-
B0: 表示H*2 (二进制表示,在末尾加0)
-
B1: 表示H*2+1 (二进制表示,在末尾加1)
- 实现细节
-
NonZero实现: P1、N1和所有以B0、B1结尾的非零数字都是NonZero
-
Integer实现:
-
Z0转换为0
-
P1转换为1
-
N1转换为-1
-
B0转换为H::to_i32() * 2
-
B1转换为H::to_i32() * 2 + 1
-
NonOne实现: 所有不等于1的类型
-
NonNegOne实现: 所有不等于-1的类型
-
Unsigned实现: 所有非负整数(0、1和所有以B0、B1结尾的非负非-1数字)
- 设计模式
-
密封模式(Sealed): 防止外部类型实现这些特质
-
类型级编程: 使用类型而不是值来表示数字,在编译时进行计算
-
标记特质: 用于分类和约束类型
- 用途
这种设计通常用于:
-
编译时维度检查
-
类型安全的状态机
-
编译时计算的数学运算
-
需要强类型保证的领域
例如,可以创建类型安全的数组,其长度在类型中编码,并在编译时检查操作是否合法。
这种技术虽然增加了编译时复杂度,但可以提供更强的类型安全和运行时零成本抽象。