一、源码
代码实现了Rust的类型级二进制数的左移运算(<<),使用类型系统在编译期进行计算。
use super::basic::{Z0, P1, N1, B0, B1, NonZero, NonOne, Unsigned};
use super::sub1::Sub1;
use core::ops::Shl;
// ==================== 左移运算(<<) ====================
// Z0 << U
impl<R: Unsigned> Shl<R> for Z0 {
type Output = Z0;
fn shl(self, _: R) -> Self::Output {
Z0 // 0 << n = 0
}
}
// P1 << U
impl Shl<Z0> for P1 {// P1 << Z0
type Output = Self;
fn shl(self, _: Z0) -> Self::Output {
self
}
}
impl Shl<P1> for P1 {// P1 << P1
type Output = B0<P1>;
fn shl(self, _: P1) -> Self::Output {
B0::new()
}
}
impl<R: Unsigned + NonZero + NonOne + Sub1> Shl<R> for P1
where
P1: Shl<<R as Sub1>::Output>
{// P1 << 超过1的数
type Output = B0<<P1 as Shl<R::Output>>::Output>;
fn shl(self, _: R) -> Self::Output {
B0::new()
}
}
// N1 << U
impl Shl<Z0> for N1 {// N1 << Z0
type Output = Self;
fn shl(self, _: Z0) -> Self::Output {
self
}
}
impl Shl<P1> for N1 {// N1 << P1
type Output = B0<N1>;
fn shl(self, _: P1) -> Self::Output {
B0::new()
}
}
impl<R: Unsigned + NonZero + NonOne + Sub1> Shl<R> for N1
where
N1: Shl<<R as Sub1>::Output>
{// P1 << 超过1的数
type Output = B0<<N1 as Shl<R::Output>>::Output>;
fn shl(self, _: R) -> Self::Output {
B0::new()
}
}
// B0 << U
impl<H: NonZero> Shl<Z0> for B0<H> {// B0 << Z0
type Output = Self;
fn shl(self, _: Z0) -> Self::Output {
self
}
}
impl<H: NonZero> Shl<P1> for B0<H> {// B0 << P1
type Output = B0<B0<H>>;
fn shl(self, _: P1) -> Self::Output {
B0::new()
}
}
impl<H: NonZero, R: Unsigned + NonZero + NonOne + Sub1> Shl<R> for B0<H>
where
B0<H>: Shl<<R as Sub1>::Output>
{// B0 << 超过1的数
type Output = B0<<B0<H> as Shl<R::Output>>::Output>;
fn shl(self, _: R) -> Self::Output {
B0::new()
}
}
// B1 << U
impl<H: NonZero> Shl<Z0> for B1<H> {// B1 << Z0
type Output = Self;
fn shl(self, _: Z0) -> Self::Output {
self
}
}
impl<H: NonZero> Shl<P1> for B1<H> {// B1 << P1
type Output = B0<B1<H>>;
fn shl(self, _: P1) -> Self::Output {
B0::new()
}
}
impl<H: NonZero, R: Unsigned + NonZero + NonOne + Sub1> Shl<R> for B1<H>
where
B1<H>: Shl<<R as Sub1>::Output>
{// B1 << 超过1的数
type Output = B0<<B1<H> as Shl<R::Output>>::Output>;
fn shl(self, _: R) -> Self::Output {
B0::new()
}
}
二、类型和trait引入
use super::basic::{Z0, P1, N1, B0, B1, NonZero, NonOne, Unsigned};
use super::sub1::Sub1;
use core::ops::Shl;
从父模块引入基础类型:
Z0: 表示0
P1: 表示+1
N1: 表示-1
B0, B1: 二进制位(0和1)
标记trait: NonZero, NonOne, Unsigned
Sub1: 减1操作
Shl: Rust的左移运算符trait
三、零的左移实现
impl<R: Unsigned> Shl<R> for Z0 {
type Output = Z0;
fn shl(self, _: R) -> Self::Output {
Z0 // 0 << n = 0
}
}
任何数左移0还是0
适用于所有无符号类型R
四、正一(P1)的左移
impl Shl<Z0> for P1 { // P1 << 0 = P1
type Output = Self;
fn shl(self, _: Z0) -> Self::Output { self }
}
impl Shl<P1> for P1 { // P1 << 1 = B0<P1> (即10,二进制表示)
type Output = B0<P1>;
fn shl(self, _: P1) -> Self::Output { B0::new() }
}
impl<R: Unsigned + NonZero + NonOne + Sub1> Shl<R> for P1
where P1: Shl<<R as Sub1>::Output> {
type Output = B0<<P1 as Shl<R::Output>>::Output>;
fn shl(self, _: R) -> Self::Output { B0::new() }
}
分三种情况处理:
移0位:保持不变
移1位:变成B0(二进制10)
移多位:递归处理
五、负一(N1)的左移
impl Shl<Z0> for N1 { ... } // 同P1
impl Shl<P1> for N1 { ... } // 同P1
impl<R: Unsigned + NonZero + NonOne + Sub1> Shl<R> for N1 { ... } // 同P1
- 处理逻辑与P1完全相同
六、B0(二进制0)的左移
impl<H: NonZero> Shl<Z0> for B0<H> { ... } // 移0位
impl<H: NonZero> Shl<P1> for B0<H> { ... } // 移1位
impl<H: NonZero, R: Unsigned + NonZero + NonOne + Sub1> Shl<R> for B0<H> { ... } // 移多位
在二进制数前补0:
B0 << 1 = B0<B0>
递归处理多位移动
七、B1(二进制1)的左移
impl<H: NonZero> Shl<Z0> for B1<H> { ... } // 移0位
impl<H: NonZero> Shl<P1> for B1<H> { ... } // 移1位
impl<H: NonZero, R: Unsigned + NonZero + NonOne + Sub1> Shl<R> for B1<H> { ... } // 移多位
- 类似B0,但在二进制数低位补0
八、关键点总结
递归处理:多位移动通过递归减1实现
类型级计算:所有操作在编译期确定
二进制表示:
B0表示在二进制数H低位加0
B1表示在二进制数H低位加1
- 特殊值处理:
P1表示+1(二进制1)
N1表示-1
Z0表示0
这种实现方式常用于需要编译期计算的场景,如物理单位系统、矩阵运算等,可以完全消除运行时开销。