【rust语言】rust多态实现方式
文章目录
- 前言
- 一、多态
- 二、rust实现多态
- trait的静态方式
- 还有一种方式可以通过动态分发,还以上面那段代码,比如
- dyn关键字
- 泛型方式
- 枚举方式
- 优点:
- 缺点:
- 总结
前言
学习rust当中遇到了这个问题,记录一下,不对地方望指正
一、多态
多态是面向对象程序设计中的一个重要概念,指同一个行为或操作在不同实例上具有不同的行为或结果。简单来说,多态就是指同一种类型的对象,在不同的上下文中有不同的行为。多态性使得程序可以更加灵活、可扩展和易于维护。在实现多态性时,通常会使用继承、接口、抽象类等技术
二、rust实现多态
trait的静态方式
trait Animal {fn make_sound(&self);
}
struct Cat {}impl Animal for Cat {fn make_sound(&self) {println!("Meow");}
}
struct Dog {}impl Animal for Dog {fn make_sound(&self) {println!("Woof");}
}fn main() {let cat: Cat = Cat {};let dog: Dog = Dog {};test(cat);test(dog)
}
//接受Animal Trait类型的
fn test(animal : impl Animal){animal.make_sound()
}
定义了方法传入参数是trait。这一种在实例化的时候是具体的类型,在传参的时候编译器能推断出来具体是cat还是dog,能调用具体方法
还有一种方式可以通过动态分发,还以上面那段代码,比如
trait Animal {fn make_sound(&self);
}struct Cat {}impl Animal for Cat {fn make_sound(&self) {println!("Meow");}
}struct Dog {}impl Animal for Dog {fn make_sound(&self) {println!("Woof");}
}fn main() {let cat: Box<dyn Animal> = Box::new(Cat {});let dog: Box<dyn Animal> = Box::new(Dog {});test(cat);test(dog)
}fn test(animal: Box<dyn Animal>) {animal.make_sound()
}
这种方式相对于上面更加灵活,因为实例化参数变量类型是trait类型。现在说说关键点
dyn关键字
dyn关键字是在Rust中用于创建和使用动态分发的trait对象的关键字。trait对象允许我们以统一的方式处理不同类型的对象,并使用相同的方法调用语法。使用动态分发,编译器无需在编译时知道具体的类型,而是在运行时根据对象的实际类型来确定要调用的方法。要创建一个trait对象,需要在trait名称前加上dyn关键字。例如,对于名为TraitName的trait,我们可以使用dyn TraitName来创建一个trait对象。
trait TraitName {// trait定义
}fn main() {let trait_obj: Box<dyn TraitName> = Box::new(ConcreteType);// 在这里使用trait对象
}
在上面的代码中,trait_obj是一个Box指向动态分发的trait对象的指针。它可以存储实现了TraitName trait的任何具体类型的对象。通过dyn关键字,我们可以在运行时根据实际类型来调用trait定义的方法。
这里要注意,trait对象通过指针或引用来操作,因此通常结合使用Box、&或&mut来创建和使用trait对象。为了在运行时确定对象的大小,我们需要将它们放置在一个固定大小的容器中。这就是为什么要使用Box来包装trait对象的原因。Box类型表示一个动态分发的trait对象。它在堆上分配一块内存,该内存用于存储对象的数据,并提供一个指向虚函数表(vtable)的指针,该表用于在运行时查找和调用正确的方法。
这种方式相对于静态方式会更加灵活,但会有运行时性能损失,看情况决定使用哪一种
泛型方式
use std::fmt::{Display, Formatter};struct Cat {}struct Dog {}impl Display for Cat{fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {write!(f,"Cat")}
}impl Display for Dog{fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {write!(f,"Dog")}
}fn make_sound<T: Display>(animal: T) {println!("{}", animal);
}fn main() {make_sound(Cat{});make_sound(Dog{});
}
通过在函数签名中使用泛型类型参数,函数可以接受不同类型的参数,并在编译时生成对应的具体化代码。这种方式不依赖于trait,而是基于类型推断和编译时的静态分发
枚举方式
还有一种方式是使用枚举方式,例如
enum Shape {Circle(f64),Square(f64),Rectangle(f64, f64),
}impl Shape {fn area(&self) -> f64 {match *self {Shape::Circle(radius) => std::f64::consts::PI * radius * radius,Shape::Square(side_length) => side_length * side_length,Shape::Rectangle(length, width) => length * width,}}
}fn main() {let circle = Shape::Circle(5.0);let square = Shape::Square(4.0);let rectangle = Shape::Rectangle(3.0, 6.0);test(circle);test(square);test(rectangle);
}fn test(shape: Shape) {println!("shape area: {}", shape.area());
}
枚举在实现多态性方面有一些优点和缺点。以下是其中的一些:
优点:
简洁性:枚举提供了一种紧凑的方式来定义和组织具有不同变体的数据类型。它能够在一个地方集中描述和管理多种可能的状态或情况。
静态类型检查:由于枚举的变体是预先定义的,编译器可以在编译时验证变体的正确性。这可以帮助捕捉到潜在的错误,并提供类型安全性。
模式匹配:枚举与模式匹配相结合,可以使代码更具表达力和可读性。模式匹配可以根据具体的变体类型执行相应的逻辑,同时处理所有可能的情况,避免遗漏。
缺点:
限制的扩展性:当需要添加新的变体时,枚举需要进行修改。这可能涉及到修改已有的代码,以适应新的变体。这对于外部库或包的枚举类型来说尤其困难,因为无法直接修改其定义。
冗余的结构:枚举的每个变体都可以存储不同的数据结构,这可能会导致某些变体拥有与其他变体不相关的冗余数据。这可能会浪费内存空间,尤其是当只使用其中的一部分变体时。
灵活性的限制:枚举要求提前定义所有可能的变体。如果需要在运行时动态添加新的变体,或者处理不确定的类型集合,那么枚举可能不适合。
总结
以上就是今天要说的内容,不对的地方望指正
相关文章:
【rust语言】rust多态实现方式
文章目录 前言一、多态二、rust实现多态trait的静态方式还有一种方式可以通过动态分发,还以上面那段代码,比如dyn关键字 泛型方式枚举方式优点:缺点: 总结 前言 学习rust当中遇到了这个问题,记录一下,不对…...
两年半机场,告诉我如何飞翔
为说明如何坐飞机离港,故此记录一篇。何为离港,顾名思义,离开港湾,那何为港湾,便是机场。 机场,一个你可能经常去,亦或不曾去之地。我想,管你去没去过,先说下怎么去&…...
【动手学深度学习】--21.锚框
锚框 学习视频:锚框【动手学深度学习v2】 官方笔记:锚框 1.锚框 目标检测算法通常会在输入图像中采样大量的区域,然后判断这些区域中是否包含我们感兴趣的目标,并调整区域边界从而更准确地预测目标的真实边界框(gro…...
C语言学习笔记(完整版)
文章目录 算法算法的基本概念算法的特征算法的优劣 描述算法三种基本结构流程图N-S流程图伪代码 常量和变量了解数据类型常量整形常量实型常量字符型常量转义字符符号常量 变量整形变量实型变量字符型变量 表达式与运算符赋值运算符和赋值表达式变量赋初值强制类型转换 算术运算…...
【Unity3D赛车游戏】【四】在Unity中添加阿克曼转向,下压力,质心会让汽车更稳定
👨💻个人主页:元宇宙-秩沅 👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 秩沅 原创 👨💻 收录于专栏:Uni…...
Python爬虫requests判断请求超时并重新post/get发送请求
在使用Python爬虫中,你可以使用requestsimport requests #Python爬虫requests判断请求超时并重新post发送请求,proxies为代理 def send_request_post(url, data, headers , proxies , max_retries3, timeout5):retries 0while retries < max_retries…...
CSS中如何实现多列布局?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 多列布局(Multi-column Layout)⭐ column-count⭐ column-width⭐ column-gap⭐ column-rule⭐ column-span⭐ 示例⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧…...
【C++】string简单实用详解
本片要分享的内容是有关于string的知识,在这之前得介绍一下什么是STL; 目录 1.STL简单介绍 2. string简单介绍 3.string简单使用 3.1.string的定义 3.2.字符串的拼接 3.3.string的遍历 3.3.1.循环遍历 3.3.2.迭代器遍历 4.string的函数构造 1.…...
opencv 进阶16-基于FAST特征和BRIEF描述符的ORB(图像匹配)
在计算机视觉领域,从图像中提取和匹配特征的能力对于对象识别、图像拼接和相机定位等任务至关重要。实现这一目标的一种流行方法是 ORB(Oriented FAST and Rotated Brief)特征检测器和描述符。ORB 由 Ethan Rublee 等人开发,结合了…...
Unity 类Scene窗口相机控制
类Scene窗口相机控制 🍔效果 🍔效果 传送门👈...
juc基础(三)
目录 一、读写锁 1、读写锁介绍 2、ReentrantReadWriteLock 3、例子 4、小结 二、阻塞队列 1、BlockingQueue 简介 2、BlockingQueue 核心方法 3、案例 4、常见的 BlockingQueue (1)ArrayBlockingQueue(常用) (2)Li…...
c语言函数指针和指针函数的区别,以及回调函数的使用。
函数指针是什么,函数指针本质也是指针,不过是指向函数的指针,存储的是函数的地址。 指针函数是什么,指针函数其实就是返回值是指针的函数,本质是函数。 函数指针是如何定义的呢,如下 void (*pfun)(int a,int b) 这…...
什么是服务端渲染?前后端分离的优点和缺点?
一.概念 服务端渲染简单点就是服务端直接返回给客户端一个完整的页面,也就是一个完整的html页面,这个页面上已经有数据了。说到这里你可能会觉得后端怎么写页面啊,而且服务端返回页面不是加载更慢吗?错了,因为我们现在…...
【Java】优化重复冗余代码的8种方式
文章目录 前言1. 抽取公用方法2. 抽工具类3. 反射4.泛型5. 继承与多态6.使用设计模式7.自定义注解(或者说AOP面向切面)8.函数式接口和Lambda表达式 前言 日常开发中,我们经常会遇到一些重复代码。大家都知道重复代码不好,它主要有这些缺点:可…...
rabbitmq卸载重新安装3.8版本
卸载之前的版本的rabbitmq 卸载rabbitmq 卸载前先停止rabbitmq服务 /usr/lib/rabbitmq/bin/rabbitmqctl stop查看rabbitmq安装的相关列表 yum list | grep rabbitmq卸载rabbitmq相关内容 yum -y remove rabbitmq-server.noarch 卸载erlang 查看erlang安装的相关列表 …...
MyBatis分页思想和特殊字符
目录 一、MyBatis分页思想 1.1 使用场景 1.2 代码演示 二、MyBatis特殊字符 2.1代码演示 一、MyBatis分页思想 1.1 使用场景 Mybatis分页应用场景: MyBatis是一个Java持久层框架,它提供了一种将SQL查询和结果映射到Java对象的简单方式。分页是MyBa…...
设计模式大白话——命令模式
命令模式 一、概述二、经典举例三、代码示例(Go)四、总结 一、概述 顾名思义,命令模式其实和现实生活中直接下命令的动作类似,怎么理解这个命令是理解命令模式的关键!!!直接说结论是很不负责…...
[线程/C++(11)]线程池
文章目录 一、C实现线程池1. 头文件2. 测试部分 二、C11实现线程池1. 头文件2. 测试部分 一、C实现线程池 1. 头文件 #define _CRT_SECURE_NO_WARNINGS #pragma once #include<iostream> #include<string.h> #include<string> #include<pthread.h> #…...
VR防地质灾害安全教育:增强自然灾害知识,提高自我保护意识
VR防地质灾害安全教育系统是一种虚拟仿真技术,可以通过虚拟现实技术模拟地震、泥石流、滑坡等地质灾害的发生和应对过程,帮助人们提高应对突发自然灾害的能力。这种系统的优势在于可以增强自然灾害知识,提高自我保护意识,锻炼人们…...
Mybatis多对多查询案例!
在MyBatis中执行多对多查询需要使用两个主要表和一个连接表(通常称为关联表)来演示。在这个示例中,我们将使用一个示例数据库模型,其中有三个表:students、courses 和 student_courses,它们之间建立了多对多…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
