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

news2024/11/18 3:39:17

开发环境

  • 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);             // 调用函数largest
    println!("The largest number is {}", result);

    let number_list = vec![102, 34, 6000, 89, 54, 2, 43, 8];
 
    let result = largest(&number_list);            // 调用函数largest
    println!("The largest number is {}", result);
}

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

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

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

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

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

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

本章重点

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IMX6ULL_Pro网卡配置

(15条消息) 【IMX6ULL_Pro板卡学习】配置 VMware 使用双网卡_vmware配置双网卡_爱学习的小莲的博客-CSDN博客https://blog.csdn.net/qq_52201194/article/details/127474352?ops_request_misc%257B%2522request%255Fid%2522%253A%2522168223524716800182730924%2522%252C%2522…

Windows逆向安全(一)之基础知识(十一)

二维数组 二维数组初始化 int arr[3][4]{{1,2,3,4},{5,6,7,8},{9,10,11,12} };查看反汇编 7: int arr[3][4]{ 8: {1,2,3,4}, 0040D498 mov dword ptr [ebp-30h],1 0040D49F mov dword ptr [ebp-2Ch],2 0040D4A6 mov dword …

CentOS(linux)使用Docker安装nacos

1. 拉取nacos镜像 docker pull nacos/nacos-server:2.0.3 2. 创建所需文件夹(以安装在home目录下为例) 1) 创建conf文件夹 mkdir -p /home/nacos/conf a. 新增文件application.properties(或者不增加该文件,会使用默认的) 文件内容如下: # spring server.servlet.contextP…

不知道玩什么游戏的你看过来

推荐一&#xff1a;原神 《原神》游戏设定在一个名为“蒂瓦特”的奇幻世界。 被神选中的人&#xff0c;将被赐予“神之眼”&#xff0c;引导“元素之力”&#xff0c;成为“旅者”。 在旅途中&#xff0c;结识性格各异、才华横溢、能力各异的小伙伴。 我们将一起战胜强大的敌…

PyTorch实战2:彩色图片识别(CIFAR10)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章&#xff1a;365天深度学习训练营-第P2周&#xff1a;彩色图片识别&#x1f356; 原作者&#xff1a;K同学啊|接辅导、项目定制 目录 一、数据准备二、构建简单CNN网络⭐1. torch…

图扑软件 | 数字孪生智慧水泥工厂

前言 近年来&#xff0c;随着我国经济的发展和人民生活水平的提高&#xff0c;我国对于水泥行业的关注程度也越来越高&#xff0c;为了保证水泥行业的健康稳定发展&#xff0c;许多地方都在大力推动水泥生产技术创新工作。当前水泥行业的发展正处于新旧动能更迭的关键阶段&…

JavaWeb开发 —— SpringBootWeb综合案例

通过综合案例&#xff0c;我们来了解和学习在开发Web程序时&#xff0c;前端程序和后端程序以及数据库三者之间是如何交互、如何协作的&#xff0c;而通过综合案例也来掌握通过接口文档开发服务端接口的能力。 目录 一、准备工作 1. 需求说明 2. 环境搭建 3. 开发规范 二…

Postgis导出shp和gdb数据库(Postgre入门九)

背景 有时候我们需要将postgis数据库中的空间数据表导出shp格式,而PG自带的PostGIS Shapefile Import/Export Manager 导出shp大部分时候是可以用的,但是它有个缺点是,当shp字段名称超过10个字节时,字段会被切掉,如字段“afdskskkfkfjdj”被切掉后是“afdskskkfk”,所以…

文案自动修改软件-文案自动改写的免费软件下载

文章生成器ai写作机器人 随着人工智能技术的飞速发展&#xff0c;越来越多的新型产品被推向市场。其中&#xff0c;文章生成器AI写作机器人是一个备受关注的新兴行业。它使用机器学习和自然语言处理等技术&#xff0c;为用户自动生成高质量的文章和内容&#xff0c;帮助用户在…

基于OpenCV与深度神经网络——实现证件识别扫描并1比1还原证件到A4纸上

前言 1.用拍照的证件照片正反面&#xff0c;实现用证件去复印到A4纸上的效果&#xff0c;还有证件的格式化识别。 图1&#xff1a;把拍照的证件1比1还原证件到A4纸上 图2&#xff1a;证件OCR格式化识别 2.使用Yolo做目标识别,Enet做边缘检测&#xff0c;Paddle OCR做文字识别&…

【数据结构与算法】常用数据结构(一)

&#x1f600;大家好&#xff0c;我是白晨&#xff0c;一个不是很能熬夜&#xff0c;但是也想日更的人✈。如果喜欢这篇文章&#xff0c;点个赞&#x1f44d;&#xff0c;关注一下&#x1f440;白晨吧&#xff01;你的支持就是我最大的动力&#xff01;&#x1f4aa;&#x1f4…

燃气管道定位83KHZ地下电子标识器探测仪ED-8000操作说明1

1、功能简要说明 ED-8000地下电子标识器探测仪是华翔天诚推出的一款可支持模拟电子标识器&#xff08;无 ID&#xff09;探测和数字 ID 电子标识器 探测两种工作模式&#xff0c;在模拟电子标识器&#xff08;无 ID&#xff09;探测模式下&#xff0c;可探测 所有按标准频率生…

Unity-ML-Agents安装

目录 1.下载ML-Agents 1.1 前往官网 1.2 选择版本 1.3 下载文件 2.下载Anaconda 3.虚拟环境 3.1 构建虚拟环境 3.2 创建项目&#xff0c;导入package.json 3.2.1 创建项目&#xff0c;导入package.json 3.2.2 导入成功 3.2.3 将模板项目拖入unity项目中 3.3 开始训练 …

低代码感觉很能打——可视化搭建系统,把格局做大

有人说「可视化搭建系统」说到底只是重复造轮子产生的玩具&#xff1b; 有人说「可视化搭建系统」本质是组件枚举&#xff0c;毫无意义。 片面的认知必有其产生的道理&#xff0c;但我们不妨从更高的角度出发&#xff0c;并真切落地实践&#xff0c;也许你会发现&#xff1a;我…

Java面试题总结 | Java面试题总结5- 数据结构模块(持续更新)

数据结构 文章目录 数据结构顺序表和链表的区别HashMap 和 Hashtable 的区别Java中用过哪些集合&#xff0c;说说底层实现&#xff0c;使用过哪些安全的集合类Java中线程安全的基本数据结构有哪些ArrayList、Vector和LinkedList有什么共同点与区别&#xff1f;ArrayList和Linke…

怎样正确做web应用的压力测试?

web应用&#xff0c;通俗来讲就是一个网站&#xff0c;主要依托于浏览器实现其功能。 提到压力测试&#xff0c;我们想到的是服务端压力测试&#xff0c;其实这是片面的&#xff0c;完整的压力测试包含服务端压力测试和前端压力测试。 下文将从以下几部分内容展开&#xff1a…

源码简读 - AlphaFold2的2.3.2版本源码解析 (1)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/130323566 时间&#xff1a;2023.4.22 官网&#xff1a;https://github.com/deepmind/alphafold AlphaFold2是一种基于深度学习的方法…

torch中fft和ifft新旧版本使用

pytorch旧版本&#xff08;1.7之前&#xff09;中有一个函数torch.rfft()&#xff0c;但是新版本&#xff08;1.8、1.9&#xff09;中被移除了&#xff0c;添加了torch.fft.rfft()&#xff0c;但它并不是旧版的替代品。 torch.fft label_fft1 torch.rfft(label_img4, signal…

25岁走出外包后,感到迷茫了.....

我认识一个老哥&#xff0c;他前段时间从外包出来了&#xff0c;他在外包干了3年左右的点工&#xff0c;可能也是自身的原因&#xff0c;也没有想到提升自己的技术水平&#xff0c;后面觉得快废了&#xff0c;待着没意思就出来了&#xff0c;出来后他自己更迷茫了&#xff0c;本…

Linux安装Jenkins搭配Gitee自动化部署Springboot项目

目录 前言一、环境准备二、全局工具配置jdk、maven、git三、配置Gitee四、新建任务-部署Springboot项目 前言 Jenkins是一款流行的开源持续集成&#xff08;CI&#xff09;和持续交付&#xff08;CD&#xff09;工具。它可以帮助开发人员自动构建、测试和部署软件应用程序&…