【PhysUnits】15.18 Unit基础结构 (unit.rs)
一、源码
这段代码定义了一个用于表示物理单位的通用结构Unit,支持单位的自动推导和运算。
//! Unit基础结构
//!
//! 支持单位自动推导use crate::sealed::Sealed;
use core::marker::PhantomData;
use core::ops::{Add, Sub, Mul, Div};
use crate::constant::{Sum, Diff};
use super::Sied;
use super::ratio::Scaled;
use super::Unitary;/// Unit基础结构
///
/// # 类型参数
/// - `R`: 比例因子类型
/// - `S`: SI基础类型
#[derive(Debug, Clone, Copy)]
pub struct Unit<R: Scaled, S: Sied>(PhantomData<(R, S)>);impl<R: Scaled, S: Sied> Unit<R, S>{pub fn new() -> Self {Self(PhantomData)}
}impl<R: Scaled, S: Sied> Sealed for Unit<R, S>{}impl<R: Scaled, S: Sied> Unitary for Unit<R, S>{}// ================ 运算实现 ================impl<R1, R2, D1:Sied, D2:Sied> Mul<Unit<R2, D2>> for Unit<R1, D1>
whereR1: Scaled + Add<R2>,R2: Scaled,D1: Mul<D2>, // 使用标准乘法 traitSum<R1, R2>: Scaled, <D1 as Mul<D2>>::Output: Sied,
{type Output = Unit<Sum<R1, R2>, <D1 as Mul<D2>>::Output // 单位相乘>;/// 物理量乘法fn mul(self, _rhs: Unit<R2, D2>) -> Self::Output {Unit(PhantomData)}
}impl<R1, R2, D1:Sied, D2:Sied> Div<Unit<R2, D2>> for Unit<R1, D1>
whereR1: Scaled + Sub<R2>, R2: Scaled,D1: Div<D2>,Diff<R1, R2>: Scaled,<D1 as Div<D2>>::Output: Sied,
{type Output = Unit<Diff<R1, R2>, // 相减<D1 as Div<D2>>::Output>;/// 物理量除法fn div(self, _rhs: Unit<R2, D2>) -> Self::Output {Unit(PhantomData)}
}
二、基本结构
pub struct Unit<R: Scaled, S: Sied>(PhantomData<(R, S)>);
-
Unit是一个泛型结构体,使用PhantomData来持有类型参数而不实际占用空间
-
类型参数:
-
R: Scaled:比例因子类型,表示单位的缩放比例(如千米是米的1000倍)
-
S: Sied:SI基础类型,表示国际单位制中的基本单位(如米、秒、千克等)
-
三、核心特性
- 构造与标记:
-
new()方法创建一个新的Unit实例
-
实现了Sealed和Unitary trait,表明这是一个单位类型
- 单位乘法:
impl<R1, R2, D1, D2> Mul<Unit<R2, D2>> for Unit<R1, D1>
-
当两个单位相乘时:
-
比例因子R1和R2相加(Sum<R1, R2>)
-
SI基础类型D1和D2相乘(D1::Output)
-
例如:米(1, Length) × 千米(1000, Length) = 1000米²
- 单位除法:
impl<R1, R2, D1, D2> Div<Unit<R2, D2>> for Unit<R1, D1>
-
当两个单位相除时:
-
比例因子R1和R2相减(Diff<R1, R2>)
-
SI基础类型D1和D2相除(D1::Output)
-
-
例如:千米(1000, Length) ÷ 秒(1, Time) = 1000米/秒
四、设计特点
-
零成本抽象:使用PhantomData确保运行时无额外开销
-
类型安全:通过类型系统保证单位运算的正确性
-
自动推导:运算结果类型由编译器自动推导
-
组合性:支持复杂单位的组合运算
五、使用场景
这种设计常用于需要严格单位检查的物理计算库,可以防止如"1米 + 1秒"这样的类型错误,并在编译期完成单位换算和简化。
整个实现利用了Rust的类型系统和trait机制,在编译期完成单位运算的类型检查,确保物理计算的维度正确性。