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

【PhysUnits】17.2 配套变量结构体 Var(variable.rs)

一、源码

这段代码定义了一个泛型结构体 Var,用于封装数值类型并提供各种运算操作。

/** 变量结构体 Var* 该结构体泛型参数 T 需满足 Numeric 约束*/use core::ops::{Neg, Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign};
use crate::constant::Integer;
/// 定义 Numeric trait,约束 T 必须实现基本数值运算
/// 包括:
/// - 一元负号运算 (Neg)
/// - 加减乘除运算 (Add, Sub, Mul, Div)
/// - 复合赋值运算 (AddAssign, SubAssign)
/// - 从i32转换 (From<i32>)
/// - 复制语义 (Copy, Clone)
/// - 默认值 (Default)
/// - 静态生命周期 ('static)
pub trait Numeric:Neg<Output = Self> +Add<Output = Self> +Sub<Output = Self> +Mul<Output = Self> +Div<Output = Self> +AddAssign +SubAssign +From<i32> +Copy +Clone +Default +Sized +'static
{}// 为基本类型实现 Numeric trait
impl Numeric for i64 {} // i64 类型实现 Numeric
impl Numeric for f64 {} // f64 类型实现 Numeric/// 定义 Scalar trait,用于物理量取值
/// 在 Numeric 基础上增加了 MulAssign 约束
pub trait Scalar:Neg<Output = Self> +Add<Output = Self> +Sub<Output = Self> +Mul<Output = Self> +Div<Output = Self> +AddAssign +SubAssign +MulAssign +From<i32> +Copy +Clone +Default +Sized +'static
{}// 为 Var 类型实现 Scalar trait
impl Scalar for Var<i64> {} // Var<i64> 实现 Scalar
impl Scalar for Var<f64> {} // Var<f64> 实现 Scalar/// 变量结构体,封装一个泛型值 T
/// T 需要满足 Numeric 约束
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct Var<T: Numeric>(pub T);// 运算符重载实现
// =============================================/// 实现 Var 的取反运算
/// 用法: -V
impl<T: Numeric> Neg for Var<T> {type Output = Self;fn neg(self) -> Self::Output {Var(-self.0)   // 对内部值取反后包装为新 Var}
}/// 实现 Var 与 Var 的加法运算
/// 用法: V + V
impl<T: Numeric> Add for Var<T> {type Output = Self;fn add(self, b: Self) -> Self::Output {Var(self.0 + b.0) // 内部值相加后包装为新 Var}
}/// 实现 Var 与 Var 的减法运算
/// 用法: V - V
impl<T: Numeric> Sub for Var<T> {type Output = Self;fn sub(self, b: Self) -> Self::Output {Var(self.0 - b.0) // 内部值相减后包装为新 Var}
}/// 实现 Var 与 Var 的乘法运算
/// 用法: V * V
impl<T: Numeric> Mul<Var<T>> for Var<T> {type Output = Self;fn mul(self, b: Self) -> Self::Output {Var(self.0 * b.0) // 内部值相乘后包装为新 Var}
}/// 实现 Var 与 Var 的除法运算
/// 用法:V / V
impl<T: Numeric> Div<Var<T>> for Var<T> {type Output = Self;fn div(self, b: Self) -> Self::Output {Var(self.0 / b.0) // 内部值相除后包装为新 Var}
}/// 实现 Var 的加法赋值运算
/// 用法: V += V
impl<T: Numeric> AddAssign for Var<T> {fn add_assign(&mut self, rhs: Self) {self.0 += rhs.0;  // 直接转发到底层类型的 += 运算}
}/// 实现 Var 的减法赋值运算
/// 用法: V -= V
impl<T: Numeric> SubAssign for Var<T> {fn sub_assign(&mut self, rhs: Self) {self.0 -= rhs.0;  // 直接转发到底层类型的 -= 运算}
}// 与常量运算实现
// =============================================/// 实现 Var 与常量的乘法运算
/// 用法: V * C
impl<T: Numeric, C:Integer + Mul<Var<T>>> Mul<C> for Var<T> {type Output = <C as Mul<Var<T>>>::Output;fn mul(self, c: C) -> Self::Output {c * self // 交换乘法顺序,调用常量的 * 运算符}
}/// 实现 Var 与常量的加法运算
/// 用法: V + C
impl<T: Numeric, C: Integer + Add<Var<T>>> Add<C> for Var<T> {type Output = <C as Add<Var<T>>>::Output;fn add(self, c:C) -> Self::Output {c + self // 交换加法顺序,调用常量的 + 运算符}
}/// 实现 Var 与常量的减法运算
/// 用法: V - C
impl<T: Numeric, C: Integer + Neg> Sub<C> for Var<T>
where <C as Neg>::Output: Add<Var<T>>,
{type Output = < C::Output as Add<Var<T>> >::Output;fn sub(self, c: C) -> Self::Output {-c+self // 转换为 -c + V 的形式}
}// 类型转换实现
// =============================================/// 实现从 i32 到 Var<i64> 的转换
impl From<i32> for Var<i64> {fn from(value: i32) -> Self {Var(value as i64)  // 将 i32 转换为 i64 后包装}
}/// 实现从 i32 到 Var<f64> 的转换
impl From<i32> for Var<f64> {fn from(value: i32) -> Self {Var(value as f64)  // 将 i32 转换为 f64 后包装}
}/// 实现从 i64 到 Var<i64> 的转换
impl From<i64> for Var<i64> {fn from(value: i64) -> Self {Var(value)   // 直接包装 i64 值}
}/// 实现从 f64 到 Var<f64> 的转换
impl From<f64> for Var<f64> {fn from(value: f64) -> Self {Var(value) // 直接包装 f64 值}
}/// 实现 Var 的乘法赋值运算
/// 用法: V *= V
impl<T: Numeric + MulAssign> MulAssign for Var<T> {fn mul_assign(&mut self, rhs: Self) {self.0 *= rhs.0; // 直接转发到底层类型的 *= 运算}
}/// 实现 Var 与底层类型的乘法赋值运算
/// 用法: V *= T
impl<T: Numeric + MulAssign> MulAssign<T> for Var<T> {fn mul_assign(&mut self, rhs: T) {self.0 *= rhs; // 直接使用底层类型的 *= 运算}
}

二、Trait 定义

Numeric Trait
pub trait Numeric:Neg<Output = Self> +  // 支持取反运算Add<Output = Self> +  // 支持加法Sub<Output = Self> +  // 支持减法Mul<Output = Self> +  // 支持乘法Div<Output = Self> +  // 支持除法AddAssign +           // 支持 += 操作SubAssign +          // 支持 -= 操作From<i32> +          // 可以从i32转换Copy +               // 可复制语义Clone +              // 可克隆Default +            // 有默认值Sized +              // 编译时大小已知'static             // 静态生命周期
{}

这个 trait 定义了数值类型需要满足的基本操作,为 i64 和 f64 实现了这个 trait。

Scalar Trait
pub trait Scalar: // 包含 Numeric 的所有功能,并增加 MulAssign// ... 
{}

这个 trait 用于物理量取值,为 Var 和 Var 实现了这个 trait。

三、Var 结构体

#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct Var<T: Numeric>(pub T);

这是一个泛型结构体,封装了一个数值类型 T,要求 T 必须实现 Numeric trait。它派生了一些常用 trait:

  • Debug: 支持调试打印

  • Clone, Copy: 可克隆和复制

  • PartialEq: 支持相等比较

  • Default: 有默认值

四、运算符重载

为 Var 实现了各种运算符:

一元运算
  • 取反 (-v): 通过实现 Neg trait
二元运算 (Var 与 Var)
  • 加法 (v1 + v2): 实现 Add

  • 减法 (v1 - v2): 实现 Sub

  • 乘法 (v1 * v2): 实现 Mul

  • 除法 (v1 / v2): 实现 Div

复合赋值运算
  • +=: 实现 AddAssign

  • -=: 实现 SubAssign

  • *=: 实现 MulAssign (对 Var 和底层类型 T 都实现了)

与常量的运算
  • v * c: 实现 Var 与常量 C 的乘法

  • v + c: 实现 Var 与常量 C 的加法

  • v - c: 实现 Var 与常量 C 的减法 (通过转换为 -c + v)

五、类型转换

实现了多种 From trait,支持从不同数值类型创建 Var:

  • 从 i32 创建 Var 或 Var

  • 从 i64 创建 Var

  • 从 f64 创建 Var

六、设计目的

这个 Var 结构体的主要目的是:

  1. 封装基本数值类型,为其添加额外的语义或功能

  2. 通过 trait 约束确保类型安全

  3. 提供丰富的运算符重载,使使用更直观

  4. 支持与常量的交互操作

这种设计常见于需要增强基本类型功能的场景,比如物理量计算、单位系统或代数运算库中。

http://www.xdnf.cn/news/12815.html

相关文章:

  • 一套个人知识储备库构建方案
  • UE的AI行为树Selector和Sequence如何理解
  • 数据结构——D/串
  • comfyui 工作流中 图生视频 如何增加视频的长度到5秒
  • C++ - string 的使用 #auto #范围for #访问及遍历操作 #容量操作 #修改操作 #其他操作 #非成员函数
  • Vivado软件开发流程操作详解
  • 五年级数学知识边界总结思考-下册
  • 【会员专享数据】1980—2022年中国逐日月年潜在蒸散发栅格数据
  • JavaScript 数组学习总结
  • Spyglass:跨时钟域同步(时钟门控单元)
  • eBPF系列--BCC中提供的BPF maps高级抽象如何映射到内核的BPF maps?
  • 【Ragflow】27.RagflowPlus(v0.4.1):小版本迭代,问题修复与功能优化
  • 比较一组结构之间的变换
  • Python爬虫实战:研究PySocks库相关技术
  • Halcon案例(三):C#联合Halcon识别排线
  • 【整数逐位除法求余补〇完整版】2022-4-11
  • 1 Studying《Linux Media Documentation》
  • 深度学习模块缝合
  • 【redis】线程IO模型
  • 第16届蓝桥杯青少Stema11月 Scratch编程——初/中级组真题——行走的图形
  • GD图像处理与SESSiON
  • MySQL(63)如何进行数据库读写分离?
  • 进程与线程的区别
  • SQL Server从入门到项目实践(超值版)读书笔记 16
  • Linux多线程-进阶
  • 设计模式学习
  • AtCoder Beginner Contest 409
  • Continue 开源 AI 编程助手框架深度分析
  • C++17 和 C++20 中的新容器与工具:std::optional、std::variant 和 std::span
  • 学习python做表格6月8日补录