Rust之泛型、特性和生命期(一):基本概念

news/2024/5/9 21:07:22/文章来源:https://blog.csdn.net/md521/article/details/130322549

开发环境

  • Windows 10
  • Rust 1.69.0

 

  • VS Code 1.77.3

 项目工程

这里继续沿用上次工程rust-demo

泛型、特性和生命期 

每种编程语言都有有效处理概念重复的工具。在Rust中,一个这样的工具就是泛型:具体类型或其他属性的抽象替身。我们可以表达泛型的行为或它们与其他泛型的关系,而不知道在编译和运行代码时它们的位置会是什么。

函数可以接受一些泛型的参数,而不是像i32String这样的具体类型,就像函数接受未知值的参数一样,对多个具体值运行相同的代码。事实上,我们已经在之前的章节的Option<T>、向量Vec<T>HashMap<K, V>,以及Result<T, E>中使用了泛型。在这一章中,你将探索如何用泛型定义你自己的类型、函数和方法!

首先,我们将回顾如何提取一个函数以减少代码的重复。然后,我们将使用同样的技术,从两个仅在参数类型上有差异的函数中提取出一个泛型函数。我们还将解释如何在结构和枚举的定义中使用泛型。

然后你将学习如何使用特质以通用方式定义行为。你可以将特质与泛型结合起来,约束泛型只接受那些具有特定行为的类型,而不是任何类型。

最后,我们将讨论生命期:各种泛型,给编译器提供关于引用如何相互关联的信息。生命期允许我们给编译器提供足够的关于借用值的信息,这样它就可以确保引用在更多的情况下是有效的,而不需要我们的帮助。

通过提取一个函数来消除重复

泛型允许我们用一个代表多种类型的占位符来替换特定的类型,以消除代码的重复。在深入研究泛型语法之前,让我们先看看如何通过提取一个用代表多个值的占位符替换特定值的函数,以一种不涉及泛型类型的方式来消除重复。然后,我们将应用同样的技术来提取一个泛型的函数! 通过研究如何识别可以提取到一个函数中的重复代码,你将开始识别可以使用泛型的重复代码。

我们从示例1中的短程序开始,它可以找到一个数组种的最大的数字。

文件名: src/main.rs

fn main() {let number_list = vec![34, 50, 25, 100, 65];let mut largest = &number_list[0];for number in &number_list {if number > largest {largest = number;}}println!("The largest number is {}", largest);
}

示例1 寻找数组中的最大数字

我们在变量number_list中存储一个数组,并将数组中第一个数字的引用放在一个名为maximum的变量中。然后我们遍历数组中的所有数字,如果当前数字大于存储在largest中的数字,则替换该变量中的引用。然而,如果当前的数字小于或等于到目前为止所看到的最大的数字,变量就不会改变,代码就会转到数组中的下一个数字。在考虑了数组中的所有数字后,largest应该指的是最大的数字,在本例中是100。

我们现在的任务是在两个不同的数组中找出最大的数字。为此,我们可以选择复制清单10-1中的代码,在程序中的两个不同地方使用相同的逻辑,如示例2所示。

fn main() {let number_list = vec![34, 50, 25, 100, 65];let mut largest = &number_list[0];for number in &number_list {         // 遍历数组if number > largest {largest = number;}}println!("The largest number is {}", largest);let number_list = vec![102, 34, 6000, 89, 54, 2, 43, 8];let mut largest = &number_list[0];for number in &number_list {         // 遍历数组if number > largest {largest = number;}}println!("The largest number is {}", largest);
}

示例2:寻找两个数组中最大数字的代码

虽然这段代码是有效的,但重复代码是繁琐的,而且容易出错。当我们想改变代码时,我们还得记住在多个地方更新代码。

为了消除这种重复,我们将通过定义一个函数来创建一个抽象,该函数可以对参数中传递的任何整数的数组进行操作。这个解决方案使我们的代码更加清晰,并使我们能够抽象地表达寻找数组中最大数字的概念。

在示例3中,我们将寻找最大数字的代码提取到一个名为maximum的函数中。然后,我们调用这个函数来寻找示例2中两个数组中的最大数字。我们也可以在将来可能出现的任何其他i32值的数组中使用这个函数。

fn largest(list: &[i32]) -> &i32 {          // 通用函数,用于计算数组种的最大值let mut largest = &list[0];for item in list {if item > largest {largest = item;}}largest
}fn main() {let number_list = vec![34, 50, 25, 100, 65];let result = largest(&number_list);             // 调用函数largestprintln!("The largest number is {}", result);let number_list = vec![102, 34, 6000, 89, 54, 2, 43, 8];let result = largest(&number_list);            // 调用函数largestprintln!("The largest number is {}", result);
}

示例3:查找两个数组中最大数字的抽象代码

最大的函数有一个叫做list的参数,它代表了我们可能传入函数的任何具体的i32切片。因此,当我们调用该函数时,代码在我们传入的具体数值上运行。

综上所述,以下是我们将代码从示例2改为示例3的步骤:

  • 识别重复的代码。
  • 将重复的代码提取到函数的主体中,并在函数签名中指定该代码的输入和返回值。
  • 更新两个重复代码的实例,以调用该函数代替。

接下来,我们将使用这些相同的步骤,用泛型来减少代码的重复。就像函数主体可以对抽象list而不是具体数值进行操作一样,泛型允许代码对抽象类型进行操作。

例如,假设我们有两个函数:一个是在i32值的切片中寻找最大的项目,一个是在char值的切片中寻找最大的项目。我们将如何消除这种重复呢?让我们拭目以待!

本章重点

  • 泛型的基本概念
  • 函数抽象:提取重复代码
  • 求取数组中的最大数方法

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CorelDRAW 2023版本更新内容及安装详细教程

这里是CorelDRAW 2023版本更新内容及安装详细教程: CorelDRAW 2023是最新更新版本,在界面和功能上做了较大提升与优化: 1. 简洁界面:采用全新设计界面,简约而不简单。菜单和工具栏进行了整合与重组,更加直观。拥有自动标记和提示,易于上手使用。 2. 全新工作空间:提供“轻量…

基于51单片机的脉搏测量仪设计与实现

目录 前言 一、设计背景 二、系统功能 三、系统硬件设计 3.1 总体方案设计 3.2 信号采集电路设计 3.3 报警电路设计 3.4 下载电路 3.5 电源电路设计 3.6 OLED显示设计 3.7 键盘电路 四、系统软件设计 4.1 系统主程序设计 4.2 脉搏采集子程序设计 4.3 键盘程序设…

正式开赛|2023年“桂林银行杯”数据建模大赛暨全国大学生数学建模竞赛广西赛区热身赛

为学习贯彻党的二十大工作报告中关于加快发展数字经济、促进数字经济和实体经济深度融合的重要指示&#xff0c;不断推进数字化转型与金融科技创新&#xff0c;桂林银行联合全国大学生数学建模竞赛广西赛区组委会、广西应用数学中心&#xff08;广西大学&#xff09;共同主办20…

使用EasyExcel导出模板并设置级联下拉及其原理分析

一、概述 项目中有时会遇到需要导出一个Excel模板&#xff0c;然后在导出的Excel中填充数据&#xff0c;最终再调用接口批量把Excel中的数据导入到数据库当中的需求。 其中级联下拉选择&#xff0c;手机号校验&#xff0c;性别校验等都是比较常见的校验。 这里就已上面三种情…

王道计组(23版)3_存储系统

概述 RAM&#xff1a;随机存储器&#xff0c;任一个存储单元可以随机存取&#xff0c;易失。用作主存(DRAM)或Cache(SRAM) ROM&#xff1a;只读存储器&#xff0c;可随机读出&#xff0c;写入较慢&#xff0c;需刷新&#xff0c;非易失。Flash、SSD固态硬盘、U盘 _____SSD&…

RK3399平台开发系列讲解(PCI/PCI-E)PCIE相关配置说明

🚀返回专栏总目录 文章目录 一、DTS 配置二、menuconfig 配置三、cmdline 配置沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 本篇将介绍在使用 RK3399 平台 PCIE 时候的配置。 一、DTS 配置 ep-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>; 此项是设置 PCIe…

arthas的简单使用

目录 arthas是什么为什么要使用arthasarthas能做什么安装arthas前提准备arthas主要命令trace命令watch命令monitor命令jad命令dashboard命令Thread命令sc命令mc命令redefine命令 实战演练1.定位到需要修改的类2.将定位到的.class文件反编译成.java文件3.修改.java文件4.将修改后…

深入浅出DPDK-1.1主流包处理硬件平台

DPDK用软件的方式在通用多核处理器上演绎着数据包处理的新篇章&#xff0c;而对于数据包处理&#xff0c;多核处理器显然不是唯一的平台。支撑包处理的主流硬件平台大致可分为三个方向&#xff1a;硬件加速器、网络处理器、多核处理器。 根据处理内容、复杂度、成本、量产规模…

Scala循环中断

目录 1.使用抛出和捕获异常的方法跳出当前循环2.使用Scala中的Breaks类的break方法3.测试4.简化 使用 ._ 来引入全部内容 方便调用 在scala中无法直接使用break关键字跳出当前循环&#xff0c;但有其他方法 1.使用抛出和捕获异常的方法跳出当前循环 def main(args: Array[Str…

3105—IIS部署子站点

一、父站点 1—web.config配置 新增并设定location段落 <configuration><location path"." allowOverride"false" inheritInChildApplications"false"><system.webServer><handlers><add name"aspNetCore"…

Java -枚举的使用

一、背景及定义 枚举是在JDK1.5以后引入的。主要用途是&#xff1a;将一组常量组织起来&#xff0c;在这之前表示一组常量通常使用定义常量的方式&#xff1a; public static int final RED 1; public static int final GREEN 2; public static int final BLACK 3;但是常量…

使用 Flask 快速构建 基于langchain 和 chatGPT的 PDF摘要总结

简介 这里不对 langchain 和 chatGPT 进行介绍&#xff0c;仅对实现过程进行整理 环境 Python >3.8 Flask2.2.3 Jinja23.1.2 langchain0.0.143 openai0.27.4 实现 总结功能 使用 langchain 和 openai 接口实现总结功能 实现逻辑&#xff1a;通过text_splitter 将pdf 分…

图像分类识别(方向/重点指引)

1、继YOLO之后的高效目标检测算法&#xff1a; CenterNet 继YOLO之后的高效目标检测算法&#xff1a; CenterNet 2、百度飞浆面向 AI 行业应用场景的开源项目&#xff1a;GitHub - PaddlePaddle/PaddleX: PaddlePaddle End-to-End Development Toolkit&#xff08;『飞桨』…

APP渗透—绕过反代理、反证书检测

APP渗透—绕过反代理、反证书检测 1. 前言1.1. 无法获取数据包情况 2. 反代理2.1. 反代理情况2.1.1. 某牛牛反代理2.1.2. 某探反代理 2.2. 绕过反代理2.2.1. Proxifier设置2.2.1.1. 设置代理服务器2.2.1.2. 配置代理规则2.2.1.3. 检测状态 2.2.2. 抓包测试 2.3. 总结 3. 反证书…

牛客网Verilog刷题——VL7

牛客网Verilog刷题——VL7 题目答案 题目 根据输入信号a&#xff0c;b的大小关系&#xff0c;求解两个数的差值&#xff1a;输入信号a&#xff0c;b为8bit位宽的无符号数。如果a>b&#xff0c;则输出a-b&#xff0c;如果a≤b&#xff0c;则输出b-a。接口信号图如下&#xff…

[pgrx开发postgresql数据库扩展]3.hello world全流程解析

数据库的扩展开发框架 一般来说&#xff0c;数据库的扩展开发主要有的目的就是扩展数据库引擎的能力&#xff08;不管是用pgrx还是其他的框架都一样&#xff09;&#xff1a; 例如PostgreSQL上最著名的扩展PostGIS&#xff0c;就是扩展了PG数据库的空间数据支持能力&#xff…

4.数据结构(0x3f:从周赛中学算法 2022下)

来自0x3f【从周赛中学算法 - 2022 年周赛题目总结&#xff08;下篇&#xff09;】&#xff1a;https://leetcode.cn/circle/discuss/WR1MJP/ 包括堆&#xff08;优先队列&#xff09;、单调栈、单调队列、字典树、并查集、树状数组、线段树等。 学习这些只是开始&#xff0c;能…

软件测试之基础概念学习篇(需求 + 测试用例 + 开发模型 + 测试模型 + BUG)

文章目录 1. 什么是软件测试2. 软件测试和软件开发的区别3. 软件测试和软件调试的区别4. 什么是需求1&#xff09;以需求为依据设计测试用例 5. 测试用例是什么6. 什么是 BUG&#xff08;软件错误&#xff09;7. 五个开发模型1&#xff09;瀑布模型2&#xff09;螺旋模型3&…

PM866 3BSE050200R1高压变频器的四种控制方法

PM866 3BSE050200R1高压变频器的四种控制方法 高压变频器装置指驱动输入电源为6&#xff0c;000V或10KV的电机装置&#xff0c;高压变频器一般主要有下列几种方案选择&#xff1a; 一、直接高压控制&#xff08;高成本&#xff09; 目前以采用美国罗宾康类似的无谐波变频技术&a…

(二十一)查找算法-插值查找

1 基本介绍 1.1 插值查找 插值查找算法又称插值搜索算法&#xff0c;是在二分查找算法的基础上改进得到的一种查找算法。 插值查找算法只适用于有序序列&#xff0c;换句话说&#xff0c;它只能在升序序列或者降序序列中查找目标元素。作为“改进版”的二分查找算法&#xf…