【unitrix】 3.6 类型级数转基础类型(from.rs)
一、源码
这段代码是 Rust 语言中实现类型转换(type conversion)的示例,使用了类型级编程(type-level programming)技术。它定义了一些数字类型(如零、正一、负一等)到基本数值类型(如 i8、f32 等)的转换规则。
use core::convert::From;
use crate::number::{Z0, P1, N1, B0, B1, NonZero, Var, Primitive};// 数字类型到基本类型的转换实现
// =============================================// 实现Z0(零)到各种整数类型的转换
impl From<Z0> for i8 { fn from(_: Z0) -> i8 { 0 } }
impl From<Z0> for i16 { fn from(_: Z0) -> i16 { 0 } }
impl From<Z0> for i32 { fn from(_: Z0) -> i32 { 0 } }
impl From<Z0> for i64 { fn from(_: Z0) -> i64 { 0 } }
impl From<Z0> for i128 { fn from(_: Z0) -> i128 { 0 } }// 实现P1(正一)到各种整数类型的转换
impl From<P1> for i8 { fn from(_: P1) -> i8 { 1 } }
impl From<P1> for i16 { fn from(_: P1) -> i16 { 1 } }
impl From<P1> for i32 { fn from(_: P1) -> i32 { 1 } }
impl From<P1> for i64 { fn from(_: P1) -> i64 { 1 } }
impl From<P1> for i128 { fn from(_: P1) -> i128 { 1 } }// 实现N1(负一)到各种整数类型的转换
impl From<N1> for i8 { fn from(_: N1) -> i8 { -1 } }
impl From<N1> for i16 { fn from(_: N1) -> i16 { -1 } }
impl From<N1> for i32 { fn from(_: N1) -> i32 { -1 } }
impl From<N1> for i64 { fn from(_: N1) -> i64 { -1 } }
impl From<N1> for i128 { fn from(_: N1) -> i128 { -1 } }// 实现Z0(零)到浮点类型的转换
impl From<Z0> for f32 { fn from(_: Z0) -> f32 { 0.0 } }
impl From<Z0> for f64 { fn from(_: Z0) -> f64 { 0.0 } }// 实现P1(正一)到浮点类型的转换
impl From<P1> for f32 { fn from(_: P1) -> f32 { 1.0 } }
impl From<P1> for f64 { fn from(_: P1) -> f64 { 1.0 } }// 实现N1(负一)到浮点类型的转换
impl From<N1> for f32 { fn from(_: N1) -> f32 { -1.0 } }
impl From<N1> for f64 { fn from(_: N1) -> f64 { -1.0 } }// 二进制数字类型的转换实现
// =============================================/// 实现B0(最低位0)到Var<T>的转换
/// 转换逻辑:将高位部分值乘以2
impl<T: Primitive + From<i32>, H: NonZero + Into<T>> From<B0<H>> for Var<T> {#[inline(always)]fn from(_: B0<H>) -> Var<T> {let val: T = H::into(H::default());Var(val * T::from(2_i32))}
}/// 实现B1(最低位1)到Var<T>的转换
/// 转换逻辑:将高位部分值乘以2再加1
impl<T: Primitive + From<i32>, H: NonZero + Into<T>> From<B1<H>> for Var<T> {#[inline(always)]fn from(_: B1<H>) -> Var<T> {let val: T = H::into(H::default());Var(val * T::from(2_i32) + T::from(1_i32))}
}
二、代码分析
- 导入和基本概念
use core::convert::From;
use crate::number::{Z0, P1, N1, B0, B1, NonZero, Var, Primitive};
-
From trait 用于定义值类型之间的转换
-
Z0, P1, N1 等是自定义的类型,代表不同的数字:
-
Z0: 零
-
P1: 正一
-
N1: 负一
-
B0, B1: 二进制数字的位(0 和 1)
-
-
NonZero, Var, Primitive 是 trait,用于约束类型
- 基本数字类型转换
代码为 Z0、P1 和 N1 实现了到各种整数和浮点类型的转换:
零的转换 (Z0)
impl From<Z0> for i8 { fn from(_: Z0) -> i8 { 0 } }
// 类似的还有 i16, i32, i64, i128, f32, f64
将 Z0 类型转换为各种数值类型时,结果都是 0
正一的转换 (P1)
impl From<P1> for i8 { fn from(_: P1) -> i8 { 1 } }
// 类似的还有 i16, i32, i64, i128, f32, f64
- 将 P1 类型转换为各种数值类型时,结果都是 1
负一的转换 (N1)
impl From<N1> for i8 { fn from(_: N1) -> i8 { -1 } }
// 类似的还有 i16, i32, i64, i128, f32, f64
- 将 N1 类型转换为各种数值类型时,结果都是 -1
- 二进制数字类型的转换
这部分处理二进制数字(B0 和 B1)到 Var 的转换:
B0 的转换
impl<T: Primitive + From<i32>, H: NonZero + Into<T>> From<B0<H>> for Var<T> {fn from(_: B0<H>) -> Var<T> {let val: T = H::into(H::default());Var(val * T::from(2_i32))}
}
-
B0 表示一个二进制数字,最低位是 0,高位是 H
-
转换逻辑:将高位的值乘以 2
-
例如:如果 H 表示二进制 10(即十进制 2),那么 B0 表示 100(十进制 4)
B1 的转换
impl<T: Primitive + From<i32>, H: NonZero + Into<T>> From<B1<H>> for Var<T> {fn from(_: B1<H>) -> Var<T> {let val: T = H::into(H::default());Var(val * T::from(2_i32) + T::from(1_i32))}
}
-
B1 表示一个二进制数字,最低位是 1,高位是 H
-
转换逻辑:将高位的值乘以 2 再加 1
-
例如:如果 H 表示二进制 10(即十进制 2),那么 B1 表示 101(十进制 5)
- 关键点
-
这是一种类型级编程技术,在编译期表示和操作数字
-
Var 是一个包装类型,用于存储运行时的实际值
-
NonZero 和 Primitive trait 用于约束类型,确保它们具有所需的特性
-
#[inline(always)] 提示编译器总是内联这些简单的转换函数
这种技术常用于需要编译期计算或类型安全的数值操作的场景,如维度检查、单位系统等。