// prefix.rs//! SI Prefixes (国际单位制词头)//! //! 提供所有标准SI词头用于单位转换,仅处理10的幂次//! //! Provides all standard SI prefixes for unit conversion, handling only powers of 10.usetypenum::{Z0,P1,P2,P3,P6,P9,P12,P15,P18,P21,P24,P27,P30,N1,N2,N3,N6,N9,N12,N15,N18,N21,N24,N27,N30,Integer,IsEqual,Sum,Diff};usestd::marker::PhantomData;usestd::ops::{Add,Sub,Mul,Div};/// PrefixLike trait defines operations related to SI prefixes/// SI词头特质定义了与SI词头相关的操作pubtraitPrefixLike{/// The symbol of the prefix (e.g. "k" for kilo)/// 词头符号(例如"k"表示千)constSYMBOL:&'staticstr;/// The exponent of the prefix (e.g. 3 for kilo which means 10^3)/// 词头的幂次(例如3表示千,即10^3)constEXPONENT:i32;/// Whether the prefix is positive (exponent > 0)/// 是否是正词头(幂次>0)constIS_POSITIVE:bool={Self::EXPONENT>0};/// Whether the prefix is negative (exponent < 0)/// 是否是负词头(幂次<0)constIS_NEGATIVE:bool={Self::EXPONENT<0};}/// Prefix struct representing a power of 10/// 词头结构体,表示10的幂次#[derive(Debug, Clone, Copy, PartialEq, Eq)]pubstructPrefix<Exp:Integer>(PhantomData<Exp>);// 实现构造函数impl<Exp:Integer>Prefix<Exp>{/// Create a new Prefix instance/// 创建一个新的词头实例pubfnnew()->Self{Prefix(PhantomData)}}// 为各类型实现PrefixLike// Implement PrefixLike for various types// 无词头 / No prefiximplPrefixLikeforPrefix<Z0>{constSYMBOL:&'staticstr="";constEXPONENT:i32=0;}// 正词头 / Positive prefixesimplPrefixLikeforPrefix<P1>{constSYMBOL:&'staticstr="da";constEXPONENT:i32=1;}implPrefixLikeforPrefix<P2>{constSYMBOL:&'staticstr="h";constEXPONENT:i32=2;}implPrefixLikeforPrefix<P3>{constSYMBOL:&'staticstr="k";constEXPONENT:i32=3;}implPrefixLikeforPrefix<P6>{constSYMBOL:&'staticstr="M";constEXPONENT:i32=6;}implPrefixLikeforPrefix<P9>{constSYMBOL:&'staticstr="G";constEXPONENT:i32=9;}implPrefixLikeforPrefix<P12>{constSYMBOL:&'staticstr="T";constEXPONENT:i32=12;}implPrefixLikeforPrefix<P15>{constSYMBOL:&'staticstr="P";constEXPONENT:i32=15;}implPrefixLikeforPrefix<P18>{constSYMBOL:&'staticstr="E";constEXPONENT:i32=18;}implPrefixLikeforPrefix<P21>{constSYMBOL:&'staticstr="Z";constEXPONENT:i32=21;}implPrefixLikeforPrefix<P24>{constSYMBOL:&'staticstr="Y";constEXPONENT:i32=24;}implPrefixLikeforPrefix<P27>{constSYMBOL:&'staticstr="R";constEXPONENT:i32=27;}implPrefixLikeforPrefix<P30>{constSYMBOL:&'staticstr="Q";constEXPONENT:i32=30;}// 负词头 / Negative prefixesimplPrefixLikeforPrefix<N1>{constSYMBOL:&'staticstr="d";constEXPONENT:i32=-1;}implPrefixLikeforPrefix<N2>{constSYMBOL:&'staticstr="c";constEXPONENT:i32=-2;}implPrefixLikeforPrefix<N3>{constSYMBOL:&'staticstr="m";constEXPONENT:i32=-3;}implPrefixLikeforPrefix<N6>{constSYMBOL:&'staticstr="μ";constEXPONENT:i32=-6;}implPrefixLikeforPrefix<N9>{constSYMBOL:&'staticstr="n";constEXPONENT:i32=-9;}implPrefixLikeforPrefix<N12>{constSYMBOL:&'staticstr="p";constEXPONENT:i32=-12;}implPrefixLikeforPrefix<N15>{constSYMBOL:&'staticstr="f";constEXPONENT:i32=-15;}implPrefixLikeforPrefix<N18>{constSYMBOL:&'staticstr="a";constEXPONENT:i32=-18;}implPrefixLikeforPrefix<N21>{constSYMBOL:&'staticstr="z";constEXPONENT:i32=-21;}implPrefixLikeforPrefix<N24>{constSYMBOL:&'staticstr="y";constEXPONENT:i32=-24;}implPrefixLikeforPrefix<N27>{constSYMBOL:&'staticstr="r";constEXPONENT:i32=-27;}implPrefixLikeforPrefix<N30>{constSYMBOL:&'staticstr="q";constEXPONENT:i32=-30;}// ========== 基本操作实现 ==========// ========== 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>>forPrefix<Ea>whereEa:Integer+Add<Eb>,Eb:Integer,Sum<Ea,Eb>:Integer,{typeOutput=Prefix<Sum<Ea,Eb>>;fnmul(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>>forPrefix<Ea>whereEa:Integer+Sub<Eb>,Eb:Integer,Diff<Ea,Eb>:Integer,{typeOutput=Prefix<Diff<Ea,Eb>>;fndiv(self, _:Prefix<Eb>)->Self::Output{Prefix::new()}}// ========== 实用类型别名 ==========// ========== Useful Type Aliases ==========pubtypeNoPrefix=Prefix<Z0>;pubtypeDeca=Prefix<P1>;pubtypeHecto=Prefix<P2>;pubtypeKilo=Prefix<P3>;pubtypeMega=Prefix<P6>;pubtypeGiga=Prefix<P9>;pubtypeTera=Prefix<P12>;pubtypePeta=Prefix<P15>;pubtypeExa=Prefix<P18>;pubtypeZetta=Prefix<P21>;pubtypeYotta=Prefix<P24>;pubtypeRonna=Prefix<P27>;pubtypeQuetta=Prefix<P30>;pubtypeDeci=Prefix<N1>;pubtypeCenti=Prefix<N2>;pubtypeMilli=Prefix<N3>;pubtypeMicro=Prefix<N6>;pubtypeNano=Prefix<N9>;pubtypePico=Prefix<N12>;pubtypeFemto=Prefix<N15>;pubtypeAtto=Prefix<N18>;pubtypeZepto=Prefix<N21>;pubtypeYocto=Prefix<N24>;pubtypeRonto=Prefix<N27>;pubtypeQuecto=Prefix<N30>;/// 词头乘法结果类型 / Prefix multiplication result typepubtypePrefixMul<A,B>=<AasMul<B>>::Output;/// 词头除法结果类型 / Prefix division result typepubtypePrefixDiv<A,B>=<AasDiv<B>>::Output;/// 词头相等判断类型 / Prefix equality comparison typepubtypePrefixEq<A,B>=<AasIsEqual<B>>::Output;// ========== 调试和测试代码 ==========// ========== Debug and Test Code ==========#[cfg(test)]modtests{usesuper::*;/// 测试词头属性和基本操作/// Test prefix properties and basic operations#[test]fntest_prefix_properties(){assert_eq!(Kilo::SYMBOL,"k");assert_eq!(Kilo::EXPONENT,3);assert!(Kilo::IS_POSITIVE);assert!(!Kilo::IS_NEGATIVE);assert_eq!(Milli::SYMBOL,"m");assert_eq!(Milli::EXPONENT,-3);assert!(!Milli::IS_POSITIVE);assert!(Milli::IS_NEGATIVE);}#[test]fntest_prefix_multiplication(){let kilo =Prefix::<P3>::new();let milli =Prefix::<N3>::new();// k * m = 10^3 * 10^-3 = 10^0let result = kilo * milli;assert_eq!(result,Prefix::<Z0>::new());// M * k = 10^6 * 10^3 = 10^9 (Giga)let mega =Prefix::<P6>::new();let kilo =Prefix::<P3>::new();let result = mega * kilo;assert_eq!(result,Prefix::<P9>::new());}#[test]fntest_prefix_division(){let kilo =Prefix::<P3>::new();let milli =Prefix::<N3>::new();// k / m = 10^3 / 10^-3 = 10^6 (Mega)let result = kilo / milli;assert_eq!(result,Prefix::<P6>::new());// m / k = 10^-3 / 10^3 = 10^-6 (Micro)let result = milli / kilo;assert_eq!(result,Prefix::<N6>::new());}#[test]fntest_type_aliases(){assert_eq!(<PrefixMul<Kilo,Milli>asPrefixLike>::EXPONENT,0);assert_eq!(<PrefixDiv<Mega,Kilo>asPrefixLike>::EXPONENT,3);}}/// 调试输出实现/// Debug output implementationimpl<Exp:Integer>std::fmt::DisplayforPrefix<Exp>wherePrefix<Exp>:PrefixLike,{fnfmt(&self, f:&mutstd::fmt::Formatter<'_>)->std::fmt::Result{write!(f,"Prefix({}, 10^{})",Self::SYMBOL,Self::EXPONENT)}}
#[test]fntest_prefix_multiplication(){let kilo =Prefix::<P3>::new();let milli =Prefix::<N3>::new();let result = kilo * milli;// 应得到无前缀assert_eq!(result,Prefix::<Z0>::new());}
六、关键特性
零成本抽象 - 所有计算在编译期完成
类型安全 - 通过类型系统保证运算合法性
完整覆盖 - 支持所有标准SI词头
可组合性 - 支持词头间的各种运算
七、使用示例
let distance =1.0*Kilo::new();// 1千米let length = distance *Milli::new();// 转换为米