当前位置: 首页 > news >正文

【PhysUnits】2 SI 量纲 实现解析(prefix.rs)

源码

这是一个编译时量纲检查的物理单位库。

//! Physical Units Library with Type-Level Dimension Checking
//! 带类型级量纲检查的物理单位库
//!
//! This module provides type-safe physical unit representations using Rust's type system
//! to enforce dimensional correctness at compile time.
//! 本模块提供类型安全的物理单位表示,利用Rust类型系统在编译时强制量纲正确性
//!
//! # Examples | 示例
//! ```
//! use physunits::*;
//! use typenum::{P1, Z0, N1};
//!
//! // Define velocity unit (m/s)
//! // 定义速度单位 (米/秒)
//! type Velocity = Dimension<P1, Z0, N1, Z0, Z0, Z0, Z0>;
//!
//! // Define acceleration unit (m/s²)
//! // 定义加速度单位 (米/秒²)
//! type Acceleration = Dimension<P1, Z0, N2, Z0, Z0, Z0, Z0>;
//! ```
//!use typenum::{Integer, Sum, Diff};
use core::marker::PhantomData;
use core::ops::{Add, Sub, Mul, Div};pub use self::dimensional::Dimensional;
pub use self::alias::*;mod dimensional;
mod alias;/// Fundamental structure representing physical units with dimensional exponents
/// 表示带有量纲指数的物理单位的基础结构
///
/// # Type Parameters | 类型参数
/// - `METER`: Length dimension exponent | 长度量纲指数
/// - `KILOGRAM`: Mass dimension exponent | 质量量纲指数  
/// - `SECOND`: Time dimension exponent | 时间量纲指数
/// - `AMPERE`: Current dimension exponent | 电流量纲指数
/// - `KELVIN`: Temperature dimension exponent | 温度量纲指数
/// - `MOLE`: Amount dimension exponent | 物质量量纲指数
/// - `CANDELA`: Luminous intensity dimension exponent | 光强量纲指数
///
/// # Example | 示例
/// ```
/// use typenum::{P1, Z0, N1};
/// 
/// // Represents m¹·s⁻¹ (velocity) | 表示 m¹·s⁻¹ (速度)
/// type VelocityUnit = Dimension<P1, Z0, N1, Z0, Z0, Z0, Z0>;
/// 
/// // Represents m·kg·s⁻² (force) | 表示 m·kg·s⁻² (力)
/// type ForceUnit = Dimension<P1, P1, N2, Z0, Z0, Z0, Z0>;
/// ```
#[derive(Debug, Clone, Copy)]
pub struct Dimension<METER: Integer,KILOGRAM: Integer,SECOND: Integer,AMPERE: Integer,KELVIN: Integer,MOLE: Integer,CANDELA: Integer
>(PhantomData<(METER, KILOGRAM, SECOND, AMPERE, KELVIN, MOLE, CANDELA)>
);impl<M: Integer, KG: Integer, S: Integer, A: Integer, K: Integer, MOL: Integer, CD: Integer>
Dimension<M, KG, S, A, K, MOL, CD> {/// Creates a new unit instance/// 创建新的单位实例pub fn new() -> Self {Self(PhantomData)}
}// ========== Operator Implementations ==========
// ========== 运算符实现 ==========impl<M1, M2, KG1, KG2, S1, S2, A1, A2, K1, K2, MOL1, MOL2, CD1, CD2> Mul<Dimension<M2, KG2, S2, A2, K2, MOL2, CD2>> for Dimension<M1, KG1, S1, A1, K1, MOL1, CD1>
whereM1: Integer + Add<M2>,M2: Integer,KG1: Integer + Add<KG2>,KG2: Integer,S1: Integer + Add<S2>,S2: Integer,A1: Integer + Add<A2>,A2: Integer,K1: Integer + Add<K2>,K2: Integer,MOL1: Integer + Add<MOL2>,MOL2: Integer,CD1: Integer + Add<CD2>,CD2: Integer,Sum<M1, M2>: Integer,Sum<KG1, KG2>: Integer,Sum<S1, S2>: Integer,Sum<A1, A2>: Integer,Sum<K1, K2>: Integer,Sum<MOL1, MOL2>: Integer,Sum<CD1, CD2>: Integer,
{type Output = Dimension<Sum<M1, M2>, Sum<KG1, KG2>, Sum<S1, S2>,Sum<A1, A2>, Sum<K1, K2>, Sum<MOL1, MOL2>, Sum<CD1, CD2>>;/// Multiplies two units by adding their dimensional exponents/// 通过相加量纲指数来相乘两个单位fn mul(self, _: Dimension<M2, KG2, S2, A2, K2, MOL2, CD2>) -> Self::Output {Dimension::new()}
}impl<M1, M2, KG1, KG2, S1, S2, A1, A2, K1, K2, MOL1, MOL2, CD1, CD2> Div<Dimension<M2, KG2, S2, A2, K2, MOL2, CD2>> for Dimension<M1, KG1, S1, A1, K1, MOL1, CD1>
whereM1: Integer + Sub<M2>,M2: Integer,KG1: Integer + Sub<KG2>,KG2: Integer,S1: Integer + Sub<S2>,S2: Integer,A1: Integer + Sub<A2>,A2: Integer,K1: Integer + Sub<K2>,K2: Integer,MOL1: Integer + Sub<MOL2>,MOL2: Integer,CD1: Integer + Sub<CD2>,CD2: Integer,Diff<M1, M2>: Integer,Diff<KG1, KG2>: Integer,Diff<S1, S2>: Integer,Diff<A1, A2>: Integer,Diff<K1, K2>: Integer,Diff<MOL1, MOL2>: Integer,Diff<CD1, CD2>: Integer,
{type Output = Dimension<Diff<M1, M2>, Diff<KG1, KG2>, Diff<S1, S2>,Diff<A1, A2>, Diff<K1, K2>, Diff<MOL1, MOL2>, Diff<CD1, CD2>>;/// Divides two units by subtracting their dimensional exponents/// 通过相减量纲指数来相除两个单位fn div(self, _: Dimension<M2, KG2, S2, A2, K2, MOL2, CD2>) -> Self::Output {Dimension::new()}
}/// 量纲除法结果类型 / Dimension division result type
pub type DimensionDiv<A, B> = <A as Div<B>>::Output;/// 量纲乘法结果类型 / Dimension multiplication result type
pub type DimensionMul<A, B> = <A as Mul<B>>::Output;// ========== Debugging and Testing Code ==========
// ========== 调试和测试代码 ==========#[cfg(test)]
mod tests {use super::*;use typenum::{P1, Z0, N1, N2};/// Test unit multiplication/// 测试单位乘法#[test]fn test_unit_multiplication() {type Meter = Dimension<P1, Z0, Z0, Z0, Z0, Z0, Z0>;type Second = Dimension<Z0, Z0, P1, Z0, Z0, Z0, Z0>;type Velocity = DimensionMul<Meter, Dimension<Z0, Z0, N1, Z0, Z0, Z0, Z0>>;let _meter = Meter::new();let _second = Second::new();let _velocity: Velocity = Meter::new().mul(Second::new().div(Second::new()).div(Second::new()));// Compile-time check that velocity has correct dimensions (m/s)// 编译时检查速度有正确的量纲 (米/秒)let _: Dimension<P1, Z0, N1, Z0, Z0, Z0, Z0> = _velocity;}/// Test unit division/// 测试单位除法#[test]fn test_unit_division() {type Meter = Dimension<P1, Z0, Z0, Z0, Z0, Z0, Z0>;type Second = Dimension<Z0, Z0, P1, Z0, Z0, Z0, Z0>;type Velocity = DimensionDiv<Meter, Second>;let _velocity: Velocity = Meter::new().div(Second::new());// Compile-time check that velocity has correct dimensions (m/s)// 编译时检查速度有正确的量纲 (米/秒)let _: Dimension<P1, Z0, N1, Z0, Z0, Z0, Z0> = _velocity;}/// Test compound units/// 测试复合单位#[test]fn test_compound_units() {type Meter = Dimension<P1, Z0, Z0, Z0, Z0, Z0, Z0>;type Kilogram = Dimension<Z0, P1, Z0, Z0, Z0, Z0, Z0>;type Second = Dimension<Z0, Z0, P1, Z0, Z0, Z0, Z0>;// Force = kg·m/s²// 力 = 千克·米/秒²type Force = DimensionMul<Kilogram, DimensionDiv<Meter, DimensionMul<Second, Second>>>;let _force: Force = Kilogram::new().mul(Meter::new().div(Second::new().mul(Second::new())));// Compile-time check that force has correct dimensions (kg·m/s²)// 编译时检查力有正确的量纲 (千克·米/秒²)let _: Dimension<P1, P1, N2, Z0, Z0, Z0, Z0> = _force;}
}

二、核心设计理念

这段代码利用 Rust 的类型系统在编译期确保物理量计算的量纲正确性,通过泛型参数来表示各个基本单位的指数:

  • 使用 typenum crate 提供的类型级别数字(如 P1, Z0, N1 分别表示 +1, 0, -1)

  • 七个基本量纲对应国际单位制(SI)的七个基本单位:

    • 米(METER)、千克(KILOGRAM)、秒(SECOND)

    • 安培(AMPERE)、开尔文(KELVIN)、摩尔(MOLE)、坎德拉(CANDELA)

三、核心数据结构

pub struct Dimension<METER, KILOGRAM, SECOND, AMPERE, KELVIN, MOLE, CANDELA>(PhantomData<...>
);

这是一个零大小类型(ZST),使用 PhantomData 来持有类型参数但不占用运行时空间。每个类型参数代表对应基本单位的指数。

四、运算符重载

实现了两种核心运算:

  • 乘法运算 (Mul trait)
impl<...> Mul<Dimension<...>> for Dimension<...> {type Output = Dimension<Sum<...>, ...>;fn mul(self, _: Dimension<...>) -> Self::Output {Dimension::new()}
}

物理意义:当两个物理量相乘时,它们的量纲指数相加
示例:速度(m/s) × 时间(s) = 距离(m) → P1 + Z0 = P1 (米), N1 + P1 = Z0 (秒)

  • 除法运算 (Div trait)
impl<...> Div<Dimension<...>> for Dimension<...> {type Output = Dimension<Diff<...>, ...>;fn div(self, _: Dimension<...>) -> Self::Output {Dimension::new()}
}

物理意义:当两个物理量相除时,它们的量纲指数相减
示例:距离(m) ÷ 时间(s) = 速度(m/s) → P1 - Z0 = P1 (米), Z0 - P1 = N1 (秒)

###五、类型别名

pub type DimensionDiv<A, B> = <A as Div<B>>::Output;
pub type DimensionMul<A, B> = <A as Mul<B>>::Output;

这些别名简化了复合单位的类型声明,使代码更易读。

六、测试用例分析

测试代码验证了三种核心场景:

1.单位乘法:验证 m * (s/s²) 得到 m/s (速度)

  1. 单位除法:验证 m / s 得到 m/s (速度)

  2. 复合单位:验证 kg * (m/(s*s)) 得到 kg·m/s² (力/牛顿)

七、编译时检查机制

关键点在于:

  • 所有运算都在类型层面完成

  • 错误的量纲操作会在编译时报错

  • 测试中的 let _: Dimension<…> = … 是编译期断言

八、实际应用示例

// 定义基本单位
type Meter = Dimension<P1, Z0, Z0, Z0, Z0, Z0, Z0>;
type Second = Dimension<Z0, Z0, P1, Z0, Z0, Z0, Z0>;// 导出速度单位
type Velocity = DimensionDiv<Meter, Second>; // m/s// 导出加速度单位
type Acceleration = DimensionDiv<Velocity, Second>; // m/s²// 导出力的单位 (kg·m/s²)
type Newton = DimensionMul<Kilogram, Acceleration>;

九、设计优势

  1. 类型安全:杜绝运行时单位错误

  2. 零开销:所有检查在编译期完成

  3. 表达力强:可以表示任意复合单位

  4. 错误早发现:编译期捕获量纲不匹配

十、扩展方向

这个基础框架可以进一步扩展:

  • 添加更多运算符(如平方、开方)

  • 添加常用物理常量

  • 支持用户自定义单位

总结来说,这段代码展示了如何利用 Rust 强大的类型系统来实现编译期的物理量纲检查,是类型安全编程的典范。

相关文章:

  • el-table合并单元
  • 数据结构(三)——栈和队列
  • uniapp-文件查找失败:‘@dcloudio/uni-ui/lib/uni-icons/uni-icons.vue‘
  • 记录一次华为魔改 fusionlnsight和ai问答的狗血故事
  • git 多个提交记录合并为一个
  • 为什么强调 RESTful 的无状态性?-优雅草卓伊凡
  • A2A Hello World搭建
  • CTF杂项入门(BUUCTF-Misc第一页)
  • 智能外呼机器人的核心优势
  • 手撕基于AMQP协议的简易消息队列-7(客户端模块的编写)
  • 安装Pod网络插件时pod状态变为ImagePullBackOff
  • 贵州安全员考试内容有哪些?
  • VB自动获取彩票网页数据指南
  • VUE——自定义指令
  • MySQL基础关键_012_事务
  • PH热榜 | 2025-05-08
  • element-ui form 组件源码分享
  • GoogLeNet详解
  • 常用 svg ICON
  • 详细聊聊 Synchronized,以及锁的升级过程
  • 国家主席习近平同普京总统举行大范围会谈
  • 绿城约13.93亿元竞得西安浐灞国际港港务片区地块,区内土地楼面单价首次冲破万元
  • 上市不足一年,吉利汽车拟私有化极氪并合并:整合资源,杜绝重复投入
  • 60岁济南石化设计院党总支书记、应急管理专家李有臣病逝
  • 中方对中美就关税谈判的立场发生变化?外交部:中方立场没有任何改变
  • 金融监管总局:支持银行有序设立科技金融专门机构,推动研发机器人、低空飞行器等新兴领域的保险产品