当前位置: 首页 > 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. 数…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...