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

rust中的“继承”

文章目录

    • 前言
    • rust结构体组合
      • 公共结构体提取
      • 其他结构体中使用
      • 使用方法
    • 使用过程宏
      • 宏定义
      • 结构体中使用
      • 使用方法
      • rust编译执行过程
      • 查看过程宏生成的代码
    • 结语

前言

我是从第一门语言学习的是C#,在C#中子类可以继承基类,老鸟都给我们说学会了一门语言学第二门就简单了基本都是相通的,但当我看到rust的时候发现是相通,当通的有点差异。下面我就来给大家风险一下,C#中的继承在Rust中的差异

rust结构体组合

C#中也有结构体这个类型,这一点他们是相同的,只是语法上有一点点差异,在rust中结构体是不支持继承的,具体原因是因为Rust 的结构体是“值语义 + 内存布局固定”,一旦允许继承就会破坏这两件事
下面我们来看一下应用场景

(Rust代码)

///用户信息
pub struct User {pub id: i32,pub create_at: DateTime<Local>,pub update_at: DateTime<Local>,pub delete_at: DateTime<Local>,pub is_deleted: bool,pub name: String,pub email: String,
}
///汽车信息
pub struct Car {pub id: String,pub create_at: DateTime<Local>,pub update_at: DateTime<Local>,pub delete_at: DateTime<Local>,pub is_deleted: bool,pub car_number: String,
}

根据上面的结构体我们可以发现这两个结构体他们都拥有相同的字段;为了减少代码的冗余我们可以把他们提取出来,做成一个“基类”然后子类继承它就可以了。在C#中当然可以这样做,但是rust中不行,rust中是可以把它提取出来,但是是把它提取出来作为一个新的结构体,然后子结构体中再包含这个公共的结构体。

公共结构体提取

提取出来的公共结构体如下:

///公共属性
pub struct BaseModel<T> {///主键idpub id: T,pub create_at: DateTime<Local>,pub update_at: DateTime<Local>,pub delete_at: DateTime<Local>,pub is_deleted: bool,
}
impl<T> BaseModel<T> {///实现构造函数fn new(id: T,create_at: DateTime<Local>,update_at: DateTime<Local>,delete_at: DateTime<Local>,is_deleted: bool,) -> Self {Self {id,create_at,update_at,delete_at,is_deleted,}}
}

其他结构体中使用

///用户信息
pub struct User {pub base:BaseModel<i32>,pub name: String,pub email: String,
}
impl User {///实现构造函数pub fn new(base: BaseModel<i32>, name: String, email: String) -> Self {Self{base,name,email,}}
}
///汽车信息
pub struct Car {pub base:BaseModel<String>,pub car_number: String,
}
impl  Car{///实现构造函数pub fn new(base: BaseModel<String>,car_number: String) -> Self {Self{base,car_number}}
}

使用方法

fn main() {let now = Local::now();let base_user = BaseModel::new(1,now,now,now,false);let user=User::new(base_user,"test".to_string(),"test".to_string());println!("用户的创建时间:{}",user.base.create_at.to_string());let base_car=BaseModel::new("GUID".to_string(),now,now,now,false);let car=Car::new(base_car,"test".to_string());println!("汽车的id:{}",car.base.id.to_string());
}

执行结果如下:
在这里插入图片描述

使用过程宏

使用过程宏会是代码变得抽象,不便于阅读和调试,但是如果真想偷懒的话也可以用一用

宏定义

use chrono::Local;
#[macro_export]
macro_rules! define_model {($struct_name:ident<$ty:ident> { $($field:ident: $field_ty:ty),* $(,)? }) => {#[derive(Debug)]pub struct $struct_name<$ty> {pub id: $ty,pub create_at: ::chrono::DateTime<::chrono::Local>,pub update_at: ::chrono::DateTime<::chrono::Local>,pub delete_at: ::chrono::DateTime<::chrono::Local>,pub is_deleted: bool,$(pub $field: $field_ty,)*}impl<$ty> $struct_name<$ty> {pub fn new(id: $ty,create_at: ::chrono::DateTime<::chrono::Local>,update_at: ::chrono::DateTime<::chrono::Local>,delete_at: ::chrono::DateTime<::chrono::Local>,is_deleted: bool,$($field: $field_ty,)*) -> Self {Self {id,create_at,update_at,delete_at,is_deleted,$($field,)*}}}};
}

结构体中使用

define_model!(User<T> {name: String,email: String,
});
define_model!(Car<T> {car_number: String,
});

使用方法

fn main() {let now = Local::now();let user: User<i64> = User::new(1i64, now, now, now, false,"test".to_string(),"12323@qq.com".to_string());let car=Car::new("GUID".to_string(),now,now,now,false,"9999".to_string());println!("{:?}",car);println!("{:?}",user);
}

执行效果如下
在这里插入图片描述
图片可能看不太清除,它打印的结果如下:

PS D:\Code\Rust\测试程序\test_struct> cargo runCompiling test_struct v0.1.0 (D:\Code\Rust\测试程序\test_struct)Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.44sRunning `target\debug\test_struct.exe`
Car { id: "GUID", create_at: 2025-09-17T10:57:13.230130300+08:00, update_at: 2025-09-17T10:57:13.230130300+08:00, delete_at: 2025-09-17T10:57:13.230130300+08:00, is_deleted: false, car_number: "9999" }
User { id: 1, create_at: 2025-09-17T10:57:13.230130300+08:00, update_at: 2025-09-17T10:57:13.230130300+08:00, delete_at: 2025-09-17T10:57:13.230130300+08:00, is_deleted: false, name: "test", email: "12323@qq.com" }

很明显两个结构体中都包含的公共结构体中的字段。其实过程宏简单理解就是代码生成器,在编译的时候他会把代码生成好放入实体中,在编写程序时还是要尽可能少的使用过程宏,它会使阅读代码变得困难。

rust编译执行过程

						源码↓ 词法/解析TokenStream↓AST(抽象语法树)├─ ➤ 过程宏/声明宏展开(我们定义的过程宏在这里执行)└─ ➤ 名称解析、early lintAST↓ loweringHIR(高级中间表示)↓类型检查、trait 求解↓MIR(中级中间表示)↓LLVMIR↓二进制执行文件

查看过程宏生成的代码

查看过程宏生成的代码可以使用 cargo expand

首先需要执行以下命令安装它

cargo install cargo-expand

在这里插入图片描述

结语

rust学习起来会让你更了解程序底层的运行逻辑,很适合作为第二门学习语言。


文章转载自:

http://6CtbyX6R.fkdts.cn
http://HzS8rbm3.fkdts.cn
http://YQnmDpsY.fkdts.cn
http://fiQgTcVe.fkdts.cn
http://z0E6YALb.fkdts.cn
http://BZK8CBH6.fkdts.cn
http://05NKhv3e.fkdts.cn
http://6iCQFwTy.fkdts.cn
http://L0QPVsGQ.fkdts.cn
http://zWS5lcVD.fkdts.cn
http://16NT7DeO.fkdts.cn
http://WUZboC2t.fkdts.cn
http://9MXoebsv.fkdts.cn
http://MbBZOOvy.fkdts.cn
http://Q0a7shg5.fkdts.cn
http://THtyqGou.fkdts.cn
http://Fuh2g5yo.fkdts.cn
http://dRbSzKDJ.fkdts.cn
http://SRewfIBY.fkdts.cn
http://QkfVgDd5.fkdts.cn
http://yIRXpeeV.fkdts.cn
http://kP3WA7HP.fkdts.cn
http://WdvKxrkw.fkdts.cn
http://hjPKvUY0.fkdts.cn
http://EVYyspU2.fkdts.cn
http://61k25y2B.fkdts.cn
http://QAYrUyf2.fkdts.cn
http://1eJhwBJQ.fkdts.cn
http://sij1QduI.fkdts.cn
http://5w3nVz6P.fkdts.cn
http://www.dtcms.com/a/388121.html

相关文章:

  • PAT乙级_1087 有多少不同的值_Python_AC解法_无疑难点
  • 007 Rust字符串
  • 使用 Compose 部署 WordPress
  • Golang语言入门篇006_关键字与保留字详解
  • Class60 Transformer
  • Redis 线上故障案例分析:从救火到防火的实战指南
  • uv虚拟环境起名
  • YASKAWA安川机器人铝材焊接节气之道
  • 2025 AIME Benchmark:AI 在奥数领域的最新进展
  • 【ubuntu24.04】删除6.14内核升级6.11.0-29-generic内核nvidia驱动535到550
  • nvm下载低版本node
  • Day44 51单片机UART串行通信 软件模拟UART + 硬件UART回显
  • Freertos系列(调度机制与创建任务)
  • 深度学习(二)
  • 搭建node脚手架(六) ESLint 功能模块
  • mysql面试(2)
  • Linux系统DNS服务
  • 如何通过跳板机访问内网 Mysql 服务器
  • SSH 远程连接内网 Linux 服务器
  • Spring Cloud - 微服务监控
  • Flutter-[1]入门指导
  • Linux服务器运维自动化巡检工具
  • Java 大视界 -- Java 大数据在智能家居设备联动与场景化节能中的应用拓展(413)
  • Node.js 部署:PM2 的 Fork 与集群模式
  • 【C++上岸】C++常见面试题目--网络篇(第二十五期)
  • LangChain使用方法以OpenAI 的聊天模型GPT-4o为例
  • CephFS存储文件系统介绍
  • Java Swagger2 能显示页面但看不到一个接口
  • SSL证书有效期缩短:自动化解决方案
  • C# 多线程编程 (.NET Framework 4.0)