【PhysUnits】15.12 去Typenum库的SI 单位制词头实现(prefix.rs)
一、源码
这个 Rust 模块实现了国际单位制(SI)的所有标准词头,用于处理以10为基数的幂次单位转换。
// prefix.rs
//! SI Prefixes (国际单位制词头)
//!
//! 提供所有标准SI词头用于单位转换,仅处理10的幂次
//! 包括正词头(da, h, k等)和负词头(d, c, m等)
//!
//! Provides all standard SI prefixes for unit conversion, handling only powers of 10.
//! Includes both positive prefixes (da, h, k etc.) and negative prefixes (d, c, m etc.)use super::constant::{Integer,Const,Sum,Diff};
use core::marker::PhantomData;
use core::ops::{Add, Sub, Mul, Div};/// Prefix struct representing a power of 10
/// 词头结构体,表示10的幂次
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Prefix<Exp: Integer>(PhantomData<Exp>);impl<Exp: Integer> Prefix<Exp> {/// Create a new Prefix instance/// 创建一个新的词头实例pub fn new() -> Self {Prefix(PhantomData)}
}// ========== 基本操作实现 ==========
// ========== Basic Operations Implementation ==========/// 实现词头乘法 (10^a * 10^b = 10^(a+b))
/// Implements prefix multiplication (10^a * 10^b = 10^(a+b))
impl<Ea, Eb> Mul<Prefix<Eb>> for Prefix<Ea>
whereEa: Integer + Add<Eb>,Eb: Integer,Sum<Ea, Eb>: Integer,
{type Output = Prefix<Sum<Ea, Eb>>;fn mul(self, _: Prefix<Eb>) -> Self::Output {Prefix::new()}
}/// 实现词头除法 (10^a / 10^b = 10^(a-b))
/// Implements prefix division (10^a / 10^b = 10^(a-b))
impl<Ea, Eb> Div<Prefix<Eb>> for Prefix<Ea>
whereEa: Integer + Sub<Eb>,Eb: Integer,Diff<Ea, Eb>: Integer,
{type Output = Prefix<Diff<Ea, Eb>>;fn div(self, _: Prefix<Eb>) -> Self::Output {Prefix::new()}
}// ========== 实用类型别名 ==========
// ========== Useful Type Aliases ==========/// 无词头 / No prefix (10^0)
pub type NoPrefix = Prefix<Const<0>>;/// 十 / Deca (10^1)
pub type Deca = Prefix<Const<1>>;/// 百 / Hecto (10^2)
pub type Hecto = Prefix<Const<2>>;/// 千 / Kilo (10^3)
pub type Kilo = Prefix<Const<3>>;/// 兆 / Mega (10^6)
pub type Mega = Prefix<Const<6>>;/// 吉 / Giga (10^9)
pub type Giga = Prefix<Const<9>>;/// 太 / Tera (10^12)
pub type Tera = Prefix<Const<12>>;/// 拍 / Peta (10^15)
pub type Peta = Prefix<Const<15>>;/// 艾 / Exa (10^18)
pub type Exa = Prefix<Const<18>>;/// 泽 / Zetta (10^21)
pub type Zetta = Prefix<Const<21>>;/// 尧 / Yotta (10^24)
pub type Yotta = Prefix<Const<24>>;/// 容 / Ronna (10^27)
pub type Ronna = Prefix<Const<27>>;/// 昆 / Quetta (10^30)
pub type Quetta = Prefix<Const<30>>;/// 分 / Deci (10^-1)
pub type Deci = Prefix<Const<-1>>;/// 厘 / Centi (10^-2)
pub type Centi = Prefix<Const<-2>>;/// 毫 / Milli (10^-3)
pub type Milli = Prefix<Const<-3>>;/// 微 / Micro (10^-6)
pub type Micro = Prefix<Const<-6>>;/// 纳 / Nano (10^-9)
pub type Nano = Prefix<Const<-9>>;/// 皮 / Pico (10^-12)
pub type Pico = Prefix<Const<-12>>;/// 飞 / Femto (10^-15)
pub type Femto = Prefix<Const<-15>>;/// 阿 / Atto (10^-18)
pub type Atto = Prefix<Const<-18>>;/// 仄 / Zepto (10^-21)
pub type Zepto = Prefix<Const<-21>>;/// 幺 / Yocto (10^-24)
pub type Yocto = Prefix<Const<-24>>;/// 柔 / Ronto (10^-27)
pub type Ronto = Prefix<Const<-27>>;/// 亏 / Quecto (10^-30)
pub type Quecto = Prefix<Const<-30>>;/// 词头乘法结果类型 / Prefix multiplication result type
/// 例如:PrefixMul<Kilo, Milli> = NoPrefix (因为10^3 * 10^-3 = 10^0)
pub type PrefixMul<A, B> = <A as Mul<B>>::Output;/// 词头除法结果类型 / Prefix division result type
/// 例如:PrefixDiv<Mega, Kilo> = Kilo (因为10^6 / 10^3 = 10^3)
pub type PrefixDiv<A, B> = <A as Div<B>>::Output;
二、主要功能
-
表示SI词头:使用类型系统表示10的不同幂次(正负词头)
-
支持词头运算:提供词头间的乘法和除法运算
3.类型安全:在编译期确保单位运算的正确性
三、核心结构
pub struct Prefix<Exp: Integer>(PhantomData<Exp>);
这是一个泛型结构体,使用PhantomData来标记类型参数Exp(表示10的幂次指数),但不实际存储任何数据。
四、关键实现
基本操作
- 乘法运算:
impl<Ea, Eb> Mul<Prefix<Eb>> for Prefix<Ea>
-
实现原理:10^a * 10^b = 10^(a+b)
-
使用Sum类型计算指数和
- 除法运算:
impl<Ea, Eb> Div<Prefix<Eb>> for Prefix<Ea>
-
实现原理:10^a / 10^b = 10^(a-b)
-
使用Diff类型计算指数差
预定义词头
模块定义了所有标准SI词头,分为两类:
- 正词头(大于1):
-
Deca (da, 10^1)
-
Hecto (h, 10^2)
-
Kilo (k, 10^3)
-
一直到Quetta (10^30)
- 负词头(小于1):
-
Deci (d, 10^-1)
-
Centi (c, 10^-2)
-
Milli (m, 10^-3)
-
一直到Quecto (10^-30)
实用类型别名
pub type PrefixMul<A, B> = <A as Mul<B>>::Output;
pub type PrefixDiv<A, B> = <A as Div<B>>::Output;
这些类型别名简化了词头运算结果的引用。
五、设计特点
-
零成本抽象:使用PhantomData不增加运行时开销
-
编译期计算:所有运算在类型系统层面完成
-
类型安全:防止不合理的单位运算
-
完整覆盖:支持所有标准SI词头
六、使用示例
let kilo = Kilo::new(); // 10^3
let milli = Milli::new(); // 10^-3
let result = kilo * milli; // 类型为NoPrefix (10^0)
这种实现方式特别适合需要严格单位系统的科学计算和工程应用。