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

Rust学习(五):泛型、trait

Rust学习(五):泛型、trait

1、泛型:

相信小伙伴们一定还记得,之前我们实现了一个add函数,并指定了参数类型为:i32:

fn add(x:i32, y:i32) ->i32 {x + y
}

这里我们就会遇到一个问题,如果我们想为两个f64类型的变量进行加法运算,那么就必须为这两个f64类型的变量重载这个add函数:

fn add(x:f64, y:f64) ->f64 {x + y
}

完成函数的重载之后,就可以正常对两个f64类型的变量使用add()方法进行加法运算了!但是,如果我们要为所有数值类型的变量都实现这样一个add函数,难道要逐个类型的进行函数重载吗?那整个代码将变得过于冗余和难以管理,在Rust中为了处理这种重复性的问题,引出了泛型的概念。

泛型是对具体类型或者属性的抽象替代,实际使用中只需要表达泛型的属性,而不需要在编写代码时知道实际上是什么类型,举一个具体的例子,比如有一所学校,要求所有学生都要穿着校服进校,这时学校是对学生全体进行的要求,无论是男生,还是女生,都要穿着校服进校,此时男生就像i32类型,女生就是f64类型,而学生就是对男生和女生抽象出来的泛型。

//通过泛型实现add函数:
fn add<T>(x:T, y:T) ->T {x + y
}

上面这个函数就可以完美实现各种数值类型的数据的加法运算,在函数声明中,add后面的尖括号里存放的就是泛型参数T(实际上这里和形参一样,T,E,G…都可以)了,旨在向编译器说明这是一个泛型函数,将泛型的概念拓展开来,也可以使用到其他类型的程序组件:

// 泛型枚举:
enum Result<T, E> {  //可以看到泛型参数可以不止一个Ok(T),Err(E),
}// 泛型结构体:
struct Point<T> {x: T,y: T,
}

事实上,即便引入了泛型的概念,依然不能完全解决add函数的问题,可以试想一下:如果传入的参数是两个字符类型呢?那么编译器必然会直接报错(一点面子都不给,doge)。下面我们介绍的trait就可以实现对泛型的一种定义和限制。

2、trait:

trait可以被译为特性(似乎没有一个官方的中午翻译,特性一词可能较为符合),trait由常量,方法和类型三部分组成,它定义了一种抽象的接口,这种抽象既可以被类型实现,也可以直接继承默认实现。rust通过trait、impl可以实现类似于C++、python等语言中class中封装、继承和多态的功能,因此具备了面向对象编程的可能,下面定义了老师和学生两种类型(结构体),并实现了打招呼的trait:

trait Greete {//定义打招呼的traitfn say_hello(&self) {println!("Nice to see you!");}
}//定义Teacher和Student类型:
struct Teacher {edu: i32,teach: i32,
}struct Student {edu: i32,
}impl Greete for Student {} //学生类型直接继承Greete的say_hello打招呼方法
impl Greete for Teacher {// 教师类型要重载say_hello方法:fn say_hello(&self) {println!("Nice to see you, too!");}
}fn main() {let s = Student {edu:3};let t = Teacher {edu:30, teach:5};s.say_hello();t.say_hello();
}

好了,现在我们对trait已经有了一个基础的(模糊的,这部分确实难)理解,现在让我们来解决在泛型中遇到的问题,如何通过trait来约束泛型:

// 泛型约束:
fn outer_say_hello<T:Greete>(t:$T) {t.say_hello();
}let stu = Student{edu:12};
outer_say_hello(&stu);

在约束函数outer_say_hello函数加上了泛型约束T:Greete,表明只有实现了Greete这个trait的类型T才能调用say_hello函数,这种泛型约束被称为trait bound。当然,trait bound还有一种语法糖使用方法:impl trait,我们用这种方式,来实现对add函数的约束:

fn add(x: &impl Addable, y: &impl Addable) {x + y
}

trait和类型都可能有很多个,为了避免在尖括号过长,影响代码的可读性,rust提供了where方法:

fn some_func<T, U>(x: T, y: U) where T: trait1 + trait2U: trait1
{do_some_work();
}

泛型和trait在rust中相当重要,需要仔细理解和体悟。

相关文章:

Rust学习(五):泛型、trait

Rust学习&#xff08;五&#xff09;&#xff1a;泛型、trait 1、泛型&#xff1a; 相信小伙伴们一定还记得&#xff0c;之前我们实现了一个add函数&#xff0c;并指定了参数类型为&#xff1a;i32&#xff1a; fn add(x:i32, y:i32) ->i32 {x y }这里我们就会遇到一个问…...

智能零售柜商品识别

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于CNN-RNN的影像报告生成】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…...

2024智能机器人与自动控制国际学术会议 (IRAC 2024)

主办&#xff0c;承办&#xff0c;支持单位 会议官网 www.icirac.org 大会时间&#xff1a;2024年11月29-12月1日 大会简介 2024智能机器人与自动控制国际学术会议 &#xff08;IRAC 2024&#xff09;由华南理工大学主办&#xff0c;会议将于2024年11月29日-12月1日在中国广…...

计算机组成原理:总线与微命令

实验四 总线与微命令实验 一、实验目的 1&#xff09; 理解总线的概念和作用。 2&#xff09; 连接运算器与存储器&#xff0c;熟悉计算机的数据通路。 3&#xff09; 理解微命令与微操作的概念。 二、实验要求 1&#xff09; 做好实验预习&#xff0c;在实验之前填写好…...

10月回顾 | Apache SeaTunnel社区动态与进展一览

各位热爱 Apache SeaTunnel 的小伙伴们&#xff0c;社区10月份月报来啦&#xff0c;请查收&#xff01; 这里将记录Apache SeaTunne社区每月动态和进展&#xff0c;欢迎关注。 月度Merge之星 感谢以下小伙伴上个月为 Apache SeaTunnel 所做的精彩贡献&#xff08;排名不分先…...

网络基础(4)传输层

既然是传输层首先就要明确实在层状结构的哪里,除开物理层之外分成了四层协议: 到这里上层(应用层)的使用已经没有问题&#xff0c;之前使用的套接字都是在应用层的。 再说端口号 到一个主机收到一个报文的时候&#xff0c;这个报文中一定存在这个报文需要到的主机的ip号。如果…...

计算机的错误计算(一百五十六)

摘要 探讨 MATLAB 中双曲反余切函数 acoth(x) 在 附近数的计算精度问题。 Acoth(x)函数的定义为 例1. 已知 计算 与 直接贴图吧&#xff1a; 另外&#xff0c;16位的正确值分别为 0.1110083774360105e2 与 -0.1110083774360105e2&#xff08;ISRealsoft 提供。通过计算…...

爬虫开发工具与环境搭建——开发工具介绍

第二章&#xff1a;爬虫开发工具与环境搭建 第一节 开发工具介绍 爬虫开发需要一些合适的工具和框架来高效地抓取网页数据。在这节中&#xff0c;我们将介绍常用的开发工具&#xff0c;帮助开发者快速搭建爬虫开发环境。 1. Python与爬虫框架选择 Python因其简洁、易学的语法…...

Oracle 19c PDB克隆后出现Warning: PDB altered with errors受限模式处理

在进行一次19c PDB克隆过程中&#xff0c;发现克隆结束&#xff0c;在打开后出现了报错&#xff0c;PDB变成受限模式&#xff0c;以下是分析处理过程 09:25:48 SQL> alter pluggable database test1113 open instancesall; Warning: PDB altered with errors. Elapsed: 0…...

阿里云ACK容器如何配置pod分散在集群的不同节点上

阿里云ACK容器如何配置pod分散在集群的不同节点上 1.核心原理 是使用pod间反亲和性&#xff08;podAntiAffinity&#xff09;&#xff0c;pod间反亲和性又分为软约束反亲和和硬约束反亲和。 2.软约束反亲和和硬约束反亲和区别&#xff1a; preferredDuringSchedulingIgnore…...

Qt信号和槽

信号和槽的概念 在Linux中我们也学过信号 Signal&#xff0c;这是进程间通信的一种方式&#xff0c;这里大致分为三个要素&#xff1a; 信号源&#xff1a;谁发送的信号&#xff08;用户进程&#xff0c;系统内核&#xff0c;终端或者作业控制&#xff0c;&#xff09; 信号的类…...

Python知识点精汇!字符串:定义、截取(索引)和其内置函数

目录 一、字符串的定义 二、字符串的截取 1.截取干啥的 2.怎么用截取 3.打印多次 4.两个字符串拼接在一起 三、字符串内置函数 1.查询函数&#xff1a; &#xff08;1&#xff09;find(str,start,end) &#xff08;2&#xff09;index&#xff08;str,start,end&#…...

【CV】头盔检测区域入侵项目

文章目录 🌕项目和数据下载🌙安全帽佩戴数据集🌕收集数据数据🌕wbem格式视频转avi或者mp4🌕跑通区域入侵🌙多边形标注工具下载🌙使用Python脚本打开视频获取一张用来标注的图片🌙打开labelme标注一个多边行🌙程序可以识别的标注json格式🌙修改代码读取Json…...

大数据应用开发——实时数据处理(一)

前言 大数据应用开发——实时数据采集 大数据应用开发——实时数据处理 Flink完成Kafka中的数据消费&#xff0c;将数据分发至Kafka的dwd层中 并在HBase中进行备份 大数据应用开发——数据可视化 hadoop&#xff0c;zookeeper&#xff0c;kafka&#xff0c;flink要开启 目…...

Wireshark中的length栏位

注&#xff1a;Ethernet II的最小data length为46&#xff0c;如果小于&#xff0c;会补全到46. 1.指定网卡抓取的&#xff0c;链路为ethernet。 IPv4 Ethernet II 长度为 14 bytes - L1ipv4 header中的length包括header和payload的总长度 - L2wireshark中length表示抓取的pac…...

IDEA中创建多模块项目步骤

步骤 1&#xff1a;使用 Spring Initializr 创建父项目 打开IntelliJ IDEA&#xff0c;选择 File > New > Project。选择 Spring Initializr 并配置项目信息&#xff1a; Group ID&#xff1a;例如 com.aqian&#xff0c;用于项目的组织标识。Artifact ID&#xff1a;例…...

深度学习笔记13-卷积神经网络1

1.卷积神经网络 卷积神经网络&#xff08;CNN&#xff09;&#xff0c;它是由多个卷积层、池化层和全连接层构成的前馈神经网络。在卷积神经网络中&#xff0c;包含了可训练的卷积核&#xff0c;这使得卷积神经网络具有强大的表征学习能力。卷积神经网络通过卷积层和池化层进行…...

【新华妙笔-注册/登录安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…...

STM32电源管理—实现低功耗

注&#xff1a; 本文是学习野火的指南针开发板过程的学习笔记&#xff0c;可能有误&#xff0c;详细请看B站野火官方配套视频教程&#xff08;这个教程真的讲的很详细&#xff0c;请给官方三连吧&#xff09; 在响应绿色发展的同时&#xff0c;在很多应用场合中都对电子设备的功…...

【链路层】空口数据包详解(4):数据物理通道协议数据单元(PDU)

目录 一、概述 1.1. 头部&#xff08;Header&#xff09;结构 1.2. MIC字段的情况说明 1.3. 有效载荷&#xff08;Payload&#xff09;格式与LLID字段的关联 二、LL Data PDU 2.1. 定义与用途 2.2. 头部字段设置 2.3. 空PDU&#xff08;Empty PDU &#xff09; 2.4. 数…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...