【unitrix】 6.10 类型转换(from.rs)
一、源码
这是一个类型级别的二进制数到基本数值类型的转换库,实现了编译期的安全转换。
use core::convert::From;
use core::ops::Add;
use crate::number::{Null, O, I, B, V, Bit, BaseInt, BaseNumber};// 二进制位转换(O/I → V<T>)
impl<T: BaseInt> From<O> for V<T> where T: From<i8> { fn from(_: O) -> Self { V(T::from(0i8)) } }
impl<T: BaseInt> From<I> for V<T> where T: From<i8> { fn from(_: I) -> Self { V(T::from(1i8)) } }// 基本数字类型转换(B<Null, O>/B<Null, I> → V<T>)
impl<T: BaseInt> From<B<Null, O>> for V<T> where T: From<i8> { // 补码形式的 `0`(`Null` 为泛型嵌套结束标识,最低位是 `O`)fn from(_: B<Null, O>) -> Self { V(T::from(0i8)) }
}impl<T: BaseInt> From<B<Null, I>> for V<T> where T: From<i8> { // 补码形式的 `-1`(`Null` 为泛型嵌套结束标识,最低位是 `I`)fn from(_: B<Null, I>) -> Self { V(T::from(-1i8)) }
}// 浮点类型转换
impl From<B<Null, O>> for V<f32> { fn from(_: B<Null, O>) -> Self { V(0f32) } }
impl From<B<Null, O>> for V<f64> { fn from(_: B<Null, O>) -> Self { V(0f64) } }
impl From<B<Null, I>> for V<f32> { fn from(_: B<Null, I>) -> Self { V(-1f32) } }
impl From<B<Null, I>> for V<f64> { fn from(_: B<Null, I>) -> Self { V(-1f64) } }// 二进制数字到V<T>的转换
impl<T, HH, HL, L> From<B<B<HH, HL>, L>> for V<T>
whereT: BaseNumber + From<i8>,V<T>: Add + From<B<HH, HL>> + From<L>,HL: Bit,L: Bit,
{fn from(value: B<B<HH, HL>, L>) -> Self {V::<T>::from(value.h) * V(T::from(2i8)) + V::<T>::from(value.l)}
}// 浮点数转换
impl<H, L> From<B<B<H, L>, Null>> for V<f32>
whereV<f32>: From<B<H, L>>,L: Bit,
{fn from(value: B<B<H, L>, Null>) -> Self {V::<f32>::from(value.h)}
}impl<H, L, LH, LL> From<B<B<H, L>, B<LH, LL>>> for V<f32>
whereV<f32>: From<B<H, L>> + From<B<LH, LL>> + Add<Output = V<f32>>,L: Bit,LH: Bit,
{fn from(value: B<B<H, L>, B<LH, LL>>) -> Self {V::<f32>::from(value.h) + V::<f32>::from(value.l) * V(0.5f32)}
}impl<H, L> From<B<B<H, L>, Null>> for V<f64>
whereV<f64>: From<B<H, L>>,L: Bit,
{fn from(value: B<B<H, L>, Null>) -> Self {V::<f64>::from(value.h)}
}impl<H, L, LH, LL> From<B<B<H, L>, B<LH, LL>>> for V<f64>
whereV<f64>: From<B<H, L>> + From<B<LH, LL>> + Add<Output = V<f64>>,L: Bit,LH: Bit,
{fn from(value: B<B<H, L>, B<LH, LL>>) -> Self {V::<f64>::from(value.h) + V::<f64>::from(value.l) * V(0.5f64)}
}// 辅助转换,用于小数部分
impl<H: Bit> From<B<H, Null>> for V<f32> {fn from(value: B<H, Null>) -> Self {V::<f32>::from(value.h)}
}impl<H: Bit> From<B<H, Null>> for V<f64> {fn from(value: B<H, Null>) -> Self {V::<f64>::from(value.h)}
}impl<H: Bit, LH: Bit, LL> From<B<H, B<LH, LL>>> for V<f32> {fn from(value: B<H, B<LH, LL>>) -> Self {V::<f32>::from(value.h) + V::<f32>::from(value.l) * V(0.5f32)}
}impl<H: Bit, LH: Bit, LL> From<B<H, B<LH, LL>>> for V<f64> {fn from(value: B<H, B<LH, LL>>) -> Self {V::<f64>::from(value.h) + V::<f64>::from(value.l) * V(0.5f64)}
}
二、代码分析
- 核心类型定义:
-
O/I:表示二进制位0和1的类型标记
-
B<H, L>:二进制数的递归类型,H是高位数,L是低位数
-
V:值容器,T是目标数值类型(i8/f32/f64等)
-
Null:类型级终止标记
- 基础位转换:
impl<T: BaseInt> From<O> for V<T> {fn from(_: O) -> Self { V(T::from(0i8)) } // O → 0
}
impl<T: BaseInt> From<I> for V<T> {fn from(_: I) -> Self { V(T::from(1i8)) } // I → 1
}
- 终止条件处理:
// 补码形式的0 (..0)
impl<T: BaseInt> From<B<Null, O>> for V<T> {fn from(_: B<Null, O>) -> Self { V(T::from(0i8)) }
}// 补码形式的-1 (..1)
impl<T: BaseInt> From<B<Null, I>> for V<T> {fn from(_: B<Null, I>) -> Self { V(T::from(-1i8)) }
}
- 递归转换算法:
impl<T, HH, HL, L> From<B<B<HH, HL>, L>> for V<T>
whereT: BaseNumber + From<i8>,// 递归约束...
{fn from(value) -> Self {V::<T>::from(value.h) * V(T::from(2i8)) + V::<T>::from(value.l)// 等效于:高位值×2 + 低位值}
}
- 浮点转换特殊处理:
// 浮点整数部分
impl<H, L> From<B<B<H, L>, Null>> for V<f32> {fn from(value) -> Self { V::<f32>::from(value.h) }
}// 浮点小数部分(权重0.5)
impl<H, L, LH, LL> From<B<B<H, L>, B<LH, LL>>> for V<f32> {fn from(value) -> Self {V::<f32>::from(value.h) + // 整数部分V::<f32>::from(value.l) * V(0.5f32) // 小数部分}
}
- 设计特点:
-
类型安全:所有转换在编译期完成
-
递归结构:通过B<H,L>类型实现任意长度二进制数
-
精确控制:补码表示和浮点转换都有明确语义
-
可扩展性:通过trait约束支持新数值类型
使用示例(伪代码):
let binary = B<B<I, O>, I>; // 二进制 101 (5)
let num: V<i8> = binary.into(); // 编译期转换为5let float_bin = B<B<I, O>, B<I, O>>; // 10.10 (2.5)
let float: V<f32> = float_bin.into(); // 编译期转换为2.5
这个库典型应用场景包括:
-
硬件寄存器映射
-
二进制协议解析
-
定点数运算
-
需要编译期验证的数值计算
所有转换都在编译期完成,如果二进制格式不合法(如非数值类型转换),会在编译时报错,保证运行时安全。