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

news2025/6/9 7:53:57

一、源码

这段代码定义了一个泛型结构体 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.coloradmin.cn/o/2405128.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iview组件库:当后台返回到的数据与使用官网组件指定的字段不匹配时,进行修改某个属性名再将response数据渲染到页面上的处理

1、需求导入 当存在前端需要的数据的字段渲染到表格或者是一些公共的表格组件展示数据时的某个字段名与后台返回的字段不一致时&#xff0c;那么需要前端进行稍加处理&#xff0c;而不能直接this.list res.data;这样数据是渲染不出来的。 2、后台返回的数据类型 Datalist(pn) …

服务器 | Centos 9 系统中,如何部署SpringBoot后端项目?

系列文章目录 虚拟机 | Ubuntu 安装流程以及界面太小问题解决 虚拟机 | Ubuntu图形化系统&#xff1a; open-vm-tools安装失败以及实现文件拖放 虚拟机 | Ubuntu操作系统&#xff1a;su和sudo理解及如何处理忘记root密码 文章目录 系列文章目录前言一、环境介绍二、 使用syst…

(2025)Windows修改JupyterNotebook的字体,使用JetBrains Mono

(JetBrains Mono字体未下载就配置,这种情况我不知道能不能行,没做过实验,因为我电脑已经下载了,不可能删了那么多字体做实验,我的建议是下载JetBrains Mono字体,当你使用VsCode配置里面的JetBrains字体也很有用) 首先参考该文章下载字体到电脑上 VSCode 修改字体为JetBrains …

小番茄C盘清理:专业高效的电脑磁盘清理工具

在使用电脑的过程中&#xff0c;我们常常会遇到系统盘空间不足、磁盘碎片过多、垃圾文件堆积等问题&#xff0c;这些问题不仅会导致电脑运行缓慢&#xff0c;还可能引发系统崩溃。为了解决这些问题&#xff0c;小番茄C盘清理应运而生。它是一款专业的C盘清理软件&#xff0c;能…

AUTOSAR实战教程--标准协议栈实现DoIP转DoCAN的方法

目录 软件架构 关键知识点 第一:PDUR的缓存作用 第二:CANTP的组包拆包功能 第三:流控帧的意义 配置过程 步骤0:ECUC模块中PDU创建 步骤1:SoAD模块维持不变 步骤2:DoIP模块为Gateway功能添加Connection ​步骤3:DoIP模块为Gateway新增LA/TA/SA ​步骤4:PDUR模…

【MySQL系列】MySQL 导出表数据到文件

博客目录 一、使用 SELECT INTO OUTFILE 语句基本语法参数详解注意事项实际示例 二、使用 mysqldump 工具基本语法常用选项实际示例 三、使用 MySQL Workbench 导出导出步骤高级选项 四、其他导出方法1. 使用 mysql 命令行客户端2. 使用 LOAD DATA INFILE 的逆向操作3. 使用编程…

vue3:十五、管理员管理-页面搭建

一、页面效果 实现管理员页面,完成管理员对应角色的中文名称显示,实现搜索栏,表格基本增删改查,分页等功能 二、修改问题 1、修改搜索框传递参数问题 (1)问题图示 如下图,之前搜索后,传递的数据不直接是一个value值,而是如下图的格式 查询可知这里传递的数据定义的是…

基于51单片机的红外防盗及万年历仿真

目录 具体实现功能 设计介绍 资料内容 全部内容 资料获取 具体实现功能 具体功能&#xff1a; &#xff08;1&#xff09;实时显示年、月、日、时、分、秒、星期信息&#xff1b; &#xff08;2&#xff09;红外传感器&#xff08;仿真中用按键模拟&#xff09;检测是否有…

【飞腾AI加固服务器】全国产化飞腾+昇腾310+PCIe Switch的AI大模型服务器解决方案

以下是全国产化飞腾AI加固服务器采用飞腾昇腾PCIe Switch解决方案&#xff1a; &#x1f5a5;️ 一、硬件架构亮点 ‌国产算力双擎‌ ‌飞腾处理器‌&#xff1a;搭载飞腾FT2000/64核服务器级CPU&#xff08;主频1.8-2.2GHz&#xff09;&#xff0c;支持高并发任务与复杂计算&a…

应用层协议:HTTPS

目录 HTTPS&#xff1a;超文本传输安全协议 1、概念 2、通信过程及关键技术 2.1 通信过程 1> TLS握手协商&#xff08;建立安全通道&#xff09; 2> 加密数据传输 2.2 关键技术 1> 对称加密算法 2> 非对称加密 3> 对称加密和非对称加密组合 4> 数…

【ArcGIS技巧】—村庄规划规划用地规划状态字段生成工具

"国土空间规划后续也是走向数据治理&#xff0c;数据建库已经是涉及到城市规划、建筑、市政、农业、地理信息、测绘等等方方面面。不得不说以后数据库建设跟维护&#xff0c;是很多专业的必修课。小编就湖南省的村庄规划建库过程中规划用地用海中规划状态字段写了个小工具…

【PCIe总线】-- inbound、outbound配置

PCI、PCIe相关知识整理汇总 【PCIe总线】 -- PCI、PCIe相关实现 由之前的PCIe基础知识可知&#xff0c;pcie的组成有&#xff1a;RC&#xff08;根节点&#xff09;、siwtch&#xff08;pcie桥&#xff09;、EP&#xff08;设备&#xff09;。 RC和EP&#xff0c;以及EP和EP能…

分布式锁实战:Redisson vs. Redis 原生指令的性能对比

分布式锁实战&#xff1a;Redisson vs. Redis 原生指令的性能对比 引言 在DIY主题模板系统中&#xff0c;用户可自定义聊天室的背景、图标、动画等元素。当多个运营人员或用户同时修改同一模板时&#xff0c;若没有锁机制&#xff0c;可能出现“甲修改了背景色&#xff0c;乙…

react+taro 开发第五个小程序,解决拼音的学习

1.找一个文件夹 cmd 2.taro init 3.vscode 找开该文件夹cd help-letters 如&#xff1a;我的是(base) PS D:\react\help-letters> pnpm install 4.先编译一下吧。看下开发者工具什么反应。 pnpm dev:weapp 5.开始规则。我用cursor就是不成功。是不是要在这边差不多了&…

kafka(windows)

目录 介绍 下载 配置 测试 介绍 Kafka是一个分布式流媒体平台&#xff0c;类似于消息队列或企业信息传递系统。 下载 Kafka对于Zookeeper是强依赖&#xff0c;所以安装Kafka之前必须先安装zookeeper 官网&#xff1a;Apache Kafka 下载此安装包并解压 配置 新建log…

基于安卓的文件管理器程序开发研究源码数据库文档

摘 要 伴随着现代科技的发展潮流&#xff0c;移动互联网技术快速发展&#xff0c;各种基于通信技术的移动终端设备做的也越来越好了&#xff0c;现代智能手机大量的进入到了我们的生活中。电子产品的各种软硬技术技术的发展&#xff0c;操作系统的不断更新换代&#xff0c;谷歌…

EMC VNXe 存储系统日志收集方法

写在前面 有朋友找来看看VNXe的故障&#xff0c;这种问题总是要收集日志&#xff0c;顺便这里也分享给大家。 注意&#xff0c;VNXe和VNX 属于完全不同的产品&#xff0c;不要看名字很类似&#xff0c;操作系统已经完全重构了&#xff0c;如果说是否有联系&#xff0c;大概就…

从“人找政策”到“政策找人”:智能退税ERP数字化重构外贸生态

离境退税新政核心内容与外贸企业影响 &#xff08;一&#xff09;政策核心变化解析 退税商店网络扩容 新政明确鼓励在大型商圈、旅游景区、交通枢纽等境外旅客聚集地增设退税商店&#xff0c;并放宽备案条件至纳税信用M级企业。以上海为例&#xff0c;静安区计划新增1000家退…

以人类演示视频为提示,学习可泛化的机器人策略

25年5月来自清华大学、上海姚期智研究院和星动纪元&#xff08;RoboEra&#xff09;公司的论文“Learning Generalizable Robot Policy with Human Demonstration Video as a Prompt”。 最近的机器人学习方法通​​常依赖于从通过遥操作收集的大量机器人数据集中进行模仿学习…

SOC-ESP32S3部分:36-适配自己的板卡

飞书文档https://x509p6c8to.feishu.cn/wiki/RP4UwPrsKi4xuQkKLAAcKxD3n1b 如果你自己画了PCB板&#xff0c;需要把自己绘制的板卡配置小智AI工程&#xff0c;可以参考此文档。 下载源码 克隆或下载源码到本地&#xff0c;这里以1.5.5为例&#xff0c;大家可以自行修改其它版…