【PhysUnits】4.4 零类型(Z0)及其算术运算(zero.rs)

news2025/5/25 3:47:24

一、源码

该代码定义了一个类型系统中的零类型Z0,并为其实现了基本的算术运算(加法、减法、乘法、除法)。这是一个典型的类型级编程示例,使用Rust的类型系统在编译期进行数学运算。

//! 零类型(Z0)及其算术运算实现
//! 
//! 本模块定义了类型系统中的零类型,并为其实现了基本算术运算。
//! 所有运算遵循数学规则,特别是零元素的算术特性。

use core::ops::{Add, Sub, Mul, Div};
use core::marker::PhantomData;
use crate::sealed::Sealed;
use super::{Positive, Neg, Integer, Null};

/// 零类型实现Sealed标记trait
impl Sealed for Z0 {}

/// 类型系统中的零类型表示
///
/// # 示例
/// ```
/// use type_arithmetic::Z0;
/// 
/// let zero = Z0;
/// ```
#[derive(Eq, PartialEq, Clone, Copy, Debug, Default)]
pub struct Z0;

// ========== 加法运算实现 ==========

/// 零加零等于零
impl Add<Z0> for Z0 {
    type Output = Z0;
    
    #[inline]
    fn add(self, _rhs: Z0) -> Self::Output {
        Z0
    }
}

/// 零加正数等于该正数
impl<P: Positive> Add<P> for Z0 {
    type Output = P;
    
    #[inline]
    fn add(self, rhs: P) -> Self::Output {
        rhs
    }
}

/// 正数加零等于该正数
impl<P: Positive> Add<Z0> for P {
    type Output = P;
    
    #[inline]
    fn add(self, _rhs: Z0) -> Self::Output {
        self
    }
}

/// 负数加零等于该负数
impl<P: Positive> Add<Z0> for Neg<P> {
    type Output = Neg<P>;
    
    #[inline]
    fn add(self, _rhs: Z0) -> Self::Output {
        self
    }
}

// ========== 减法运算实现 ==========

/// 零减零等于零
impl Sub for Z0 {
    type Output = Z0;
    
    #[inline]
    fn sub(self, _rhs: Self) -> Self::Output {
        Z0
    }
}

/// 零减正数等于对应负数
impl<P: Positive> Sub<P> for Z0 {
    type Output = Neg<P>;
    
    #[inline]
    fn sub(self, _rhs: P) -> Self::Output {
        Neg::<P>::default()
    }
}

/// 零减负数等于对应正数
impl<P: Positive> Sub<Neg<P>> for Z0 {
    type Output = P;
    
    #[inline]
    fn sub(self, _rhs: Neg<P>) -> Self::Output {
        P::default()
    }
}

/// 正数减零等于该正数
impl<P: Positive> Sub<Z0> for P {
    type Output = P;
    
    #[inline]
    fn sub(self, _rhs: Z0) -> Self::Output {
        self
    }
}

/// 负数减零等于该负数
impl<P: Positive> Sub<Z0> for Neg<P> {
    type Output = Neg<P>;
    
    #[inline]
    fn sub(self, _rhs: Z0) -> Self::Output {
        self
    }
}

// ========== 乘法运算实现 ==========

/// 零乘零等于零
impl Mul for Z0 {
    type Output = Z0;
    
    #[inline]
    fn mul(self, _rhs: Self) -> Self::Output {
        Z0
    }
}

/// 零乘正数等于零
impl<P: Positive> Mul<P> for Z0 {
    type Output = Z0;
    
    #[inline]
    fn mul(self, _rhs: P) -> Self::Output {
        Z0
    }
}

/// 零乘负数等于零
impl<P: Positive> Mul<Neg<P>> for Z0 {
    type Output = Z0;
    
    #[inline]
    fn mul(self, _rhs: Neg<P>) -> Self::Output {
        Z0
    }
}

/// 正数乘零等于零
impl<P: Positive> Mul<Z0> for P {
    type Output = Z0;
    
    #[inline]
    fn mul(self, _rhs: Z0) -> Self::Output {
        Z0
    }
}

/// 负数乘零等于零
impl<P: Positive> Mul<Z0> for Neg<P> {
    type Output = Z0;
    
    #[inline]
    fn mul(self, _rhs: Z0) -> Self::Output {
        Z0
    }
}

// ========== 除法运算实现 ==========

/// 零除以正数等于零
impl<P: Positive> Div<P> for Z0 {
    type Output = Z0;
    
    #[inline]
    fn div(self, _rhs: P) -> Self::Output {
        Z0
    }
}

/// 零除以负数等于零
impl<P: Positive> Div<Neg<P>> for Z0 {
    type Output = Z0;
    
    #[inline]
    fn div(self, _rhs: Neg<P>) -> Self::Output {
        Z0
    }
}

// 注意:正数/零和负数/零未实现,因为数学上除以零未定义

#[cfg(test)]
mod tests {
    use super::*;
    use crate::{P1, N1};
    
    #[test]
    fn test_z0_addition() {
        let zero = Z0;
        let p1 = P1::default();
        let n1 = N1::default();
        
        assert_eq!(zero + p1, p1);
        assert_eq!(zero + n1, n1);
        assert_eq!(p1 + zero, p1);
        assert_eq!(n1 + zero, n1);
    }
    
    #[test]
    fn test_z0_subtraction() {
        let zero = Z0;
        let p1 = P1::default();
        let n1 = N1::default();
        
        assert_eq!(zero - p1, N1::default());
        assert_eq!(zero - n1, P1::default());
        assert_eq!(p1 - zero, p1);
        assert_eq!(n1 - zero, n1);
    }
    
    #[test]
    fn test_z0_multiplication() {
        let zero = Z0;
        let p2 = P1::default();
        let n1 = N1::default();
        
        assert_eq!(zero * p1, zero);
        assert_eq!(zero * n1, zero);
        assert_eq!(p1 * zero, zero);
        assert_eq!(n1 * zero, zero);
    }
    
    #[test]
    fn test_z0_division() {
        let zero = Z0;
        let p1 = P1::default();
        let n1 = N1::default();
        
        assert_eq!(zero / p1, zero);
        assert_eq!(zero / n1, zero);
    }
    
    #[test]
    fn test_z0_interactions() {
        let zero = Z0;
        let p1 = P1::default();
        let n1 = N1::default();
        
        assert_eq!(zero + p1, P1::default());
        assert_eq!((zero - p1) + n1, zero);
        assert_eq!((p1 + zero) * n1, N1::default());
    }
}

二、核心概念

  1. Z0类型:表示类型系统中的零值,是一个单元结构体(pub struct Z0;)

  2. 特性实现:

  • 实现了Sealed标记trait(一种设计模式,防止外部实现)

  • 实现了Add、Sub、Mul、Div等运算trait

三、运算实现细节

加法运算
  • Z0 + Z0 = Z0

  • Z0 + 正数 = 正数

  • 正数 + Z0 = 正数

  • 负数 + Z0 = 负数

减法运算
  • Z0 - Z0 = Z0

  • Z0 - 正数 = 对应负数

  • Z0 - 负数 = 对应正数

  • 正数 - Z0 = 正数

  • 负数 - Z0 = 负数

乘法运算
  • Z0 * 任何数 = Z0(符合数学中零乘以任何数等于零的规则)
除法运算
  • Z0 / 正数 = Z0

  • Z0 / 负数 = Z0

  • 没有实现任何数除以Z0(因为数学上不允许除以零)

四、测试用例

代码包含了详尽的测试用例,验证了:

  1. 零与正数(P1)、负数(N1)的加法

  2. 零与正负数之间的减法

  3. 零与正负数的乘法

  4. 零除以正负数的除法

  5. 各种运算的组合

五、设计特点

  1. 类型安全:所有运算在编译期进行类型检查

  2. 零特性:严格遵循数学中零元素的算术特性

  3. 扩展性:可以与系统中的其他数值类型(正数、负数)交互

  4. 零开销:使用Rust的零成本抽象,运行时没有额外开销

这种类型级编程技术常用于需要编译期计算和验证的场景,如维度检查、单位系统等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2385069.html

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

相关文章

Pluto实验报告——基于2ASK的简易的通信系统

一、实验目的 1. 熟悉并掌握PLUTO SDR 主动学习模块的使用&#xff1b; 2.通过matlab 编码与adalm pluto 相配合达成一个简易的通信系统&#xff0c;并能 够传输一些较为简单的信息。 二、实验原理 2ASK 调制原理&#xff1a; 振幅键控是指利用载波的振幅变化来传递数字基带信…

深入了解redis的哈希槽的知识

目录 1、哈希算法分类 1.1、简单哈希算法 1.2、一致性哈希算法 1、原理&#xff1a; 2、解决问题 3、数据倾斜问题 4、虚拟节点 2. 哈希槽 2.1、介绍 2. 2、作用 1、数据分片&#xff08;Sharding&#xff09; 2、高可用性&#xff08;HA&#xff09; 3…

农业机械化、电气化和自动化知网英文普刊:1天录用,2周见刊发表!

CSP科学出版社&#xff0c;旨在通过为研究人员提供最佳环境来发表、参考、阅读和引用他们的作品&#xff0c;从而为科学界服务。现已与科检易学术达成出版战略合作&#xff0c;现在联合共同出版高质量学术水平的期刊&#xff0c;为方便广大科研学者投稿方便&#xff0c;现已经建…

Docker-Compose使用自定义网桥后在OpenWrt系统中容器无法访问网络解决方案

Docker-Compose使用自定义bridge网桥后在OpenWrt系统中容器无法访问网络解决方案 示例compose描述文件如下&#xff0c;注意最后网络配置&#xff1a; # docker-compose --env-file .env.yoko.prod.local up -d services:...postgres:image: kuluseky/postgres-zhparser-post…

界面组件DevExpress WPF中文教程:Grid - 行和卡片

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

Qt enabled + geometry 属性(2)

文章目录 enabled属性可用与禁用的概念API接口代码演示 阐述说明1. 先简单描述下要如何演示出上面两个接口的效果&#xff08;思路&#xff09;2. 事先规范按钮对象的命名3. 定义两个按钮对象的槽函数 动图演示效果4. widget.cpp geometry属性预备知识API接口上下左右移动 ta…

Llamaindex自学笔记(完)

Llamaindex框架主要做RAG&#xff0c;工作流用LangGraph做 换源&#xff1a; -i https://pypi.mirrors.ustc.edu.cn/simple/环境搭建&#xff1a; conda create -n llamaindex python3.12 conda activate llamaindexpip install llama-index pip install llama-cloud-servic…

飞书知识问答深度测评:企业AI应用落地的“范本级”产品

前言 当 AI 逐渐从技术前沿走向日常办公&#xff0c;我们最常听到的一个词是“效率提升”。但真正能做到降本增效、让企业员工切实受益的 AI 产品&#xff0c;仍属少数。尤其是在组织内部知识管理这一块&#xff0c;大多数企业仍停留在“搜索靠关键词、记录靠记忆、协作靠问人…

draw.io的基础与进阶使用指南

前言 一、Draw.io 简介 Draw.io 是一款功能强大的绘图工具&#xff0c;支持在线使用和本地安装。它提供了丰富的模板和形状元素&#xff0c;能够绘制流程图、UML 图、甘特图、网络图等多种图形。Draw.io 的文件格式支持可编辑的矢量图和位图&#xff0c;方便后续修改 draw.io的…

Sanitizers

一、简介 sanitizers 是谷歌提供的一套开源工具&#xff0c;能够发现堆栈读写溢出、内存泄漏、线程数据竞争和死锁等问题。包括&#xff1a; AddressSanitizers (Asan):检测地址相关问题&#xff0c;如use-after-free,heap-buffer-overflow, stack_buffer_overflow,use_after_…

pip代理出现问题 ProxyError

WARNING: Retrying (Retry(total4, connectNone, readNone, redirectNone, statusNone)) after connection broken by ‘ProxyError(‘Cannot connect to proxy.’, NewConnectionError(’<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7f8347ad5ae0>: F…

vue+threeJS 创建镂空球体(SphereGeometry)

嗨&#xff0c;我是小路。今天主要和大家分享的主题是“vuethreeJS 创建镂空球体&#xff08;SphereGeometry&#xff09;”。 上次看到一个做镂空球体的项目&#xff0c;自己也准备尝试着做一做。今天终于做完了&#xff0c;并对这个项目进行梳理。 镂空球体示例效果…

[ Qt ] | 常见控件(一)

目录 Widget enable geometry 标题中的&#xff1a;有一不一定有二&#xff0c;但是有一说明还没结束。 Widget 控件(Widget)&#xff0c;是界面上各种元素&#xff0c;各种部分的统称。 Qt中的控件都是继承自QWidget这个类&#xff0c;是Qt控件体系中&#xff0c;通用的…

【八股战神篇】Java虚拟机(JVM)高频面试题

目录 专栏简介 一 请解释Java虚拟机(JVM)及其主要功能 延伸 1. JVM的基本概念 2. JVM的主要功能 二 对象创建的过程了解吗 延伸 1.Java 创建对象的四种常见方式 三 什么是双亲委派模型 延伸 1.双亲委派机制的作用: 2.双亲委派模型的核心思想: 3.双亲委派模型的…

NDVI谐波拟合(基于GEE实现)

在遥感影像中&#xff0c;我们常用 NDVI&#xff08;归一化植被指数&#xff09;来衡量地表植被的绿度。它简单直观&#xff0c;是生态监测、农情分析的基础工具。但你是否注意到&#xff1a; NDVI 虽然“绿”&#xff0c;却常常“乱”。 因为云层、观测频率、天气干扰&#xf…

南京邮电大学《智能控制技术》期末抢救(上)

一、智能控制的提出 传统控制方法包括经典控制和现代控制——基于被控对象精确模型的控制方式&#xff0c;缺乏灵活性和应变能力&#xff0c;适于解决线性、时不变性等相对简单的控制问题。传统控制方法在实际应用中遇到很多难解决的问题&#xff0c;主要表现以下几点&#xff…

TPDS-2014《Efficient $k$-means++ Approximation with MapReduce》

推荐深蓝学院的《深度神经网络加速&#xff1a;cuDNN 与 TensorRT》&#xff0c;课程面向就业&#xff0c;细致讲解CUDA运算的理论支撑与实践&#xff0c;学完可以系统化掌握CUDA基础编程知识以及TensorRT实战&#xff0c;并且能够利用GPU开发高性能、高并发的软件系统&#xf…

地理特征类可视化图像

目录 一、蜂窝热力地图 1. 特点 (1)优点 (2)缺点 2. 应用场景 3.python代码实现 (1)代码 (2)实现结果 二、变形地图 1. 特点 (1)优点 (2)缺点 2. 应用场景 3.python代码实现 (1)代码 (2)实现结果 三、关联地图 1. 特点 (1)优点 (2)缺点 2. 应用场景 3.pyth…

【Java高阶面经:微服务篇】8.高可用全链路治理:第三方接口不稳定的全场景解决方案

一、第三方接口治理的核心挑战与架构设计 1.1 不稳定接口的典型特征 维度表现影响范围响应时间P99超过2秒,波动幅度大(如100ms~5s)导致前端超时,用户体验恶化错误率随机返回5xx/429,日均故障3次以上核心业务流程中断,交易失败率上升协议不一致多版本API共存,字段定义不…

DataGridView中拖放带有图片的Excel,实现数据批量导入

1、带有DataGridView的窗体&#xff0c;界面如下 2、编写DataGridView支持拖放的代码 Private Sub DataGridView1_DragEnter(ByVal sender As Object, ByVal e As DragEventArgs) Handles DataGridView1.DragEnterIf e.Data.GetDataPresent(DataFormats.FileDrop) ThenDim file…