【Rust自学】8.1. Vector
喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)
8.1.0. 本章内容
第八章主要讲的是Rust中常见的集合。Rust中提供了很多集合类型的数据结构,这些集合可以包含很多值。但是第八章所讲的集合与数组和元组有所不同。
第八章中的集合是存储在堆内存上而非栈内存上的,这也意味着这些集合的数据大小无需在编译时就确定,在运行时它们可以动态地变大或变小。
本章主要会讲三种集合:Vector(本文)、String和HashMap
喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)
8.1.1. 使用Vector存储多个值
Vector
这个类型的写法是Vec<T>
,同样的,T
代表泛型变量,在实际使用时替换成自己需要的数据类型即可。
Vector
由标准库提供,在Vector
里可以存储多个值,而且这些值的类型是相同的,它们在内存中是连续存放的。可以把它视为可以扩展的数组。
创建Vector
可以使用Vec::new
这个函数,我们看个例子:
fn main() { let v:Vec<i32> = Vec::new();
}
这个例子很简单,就是使用Vec::new
这个函数声明了一个Vector
里边元素是i32
的变量。
在这里需要填在Vec<>
里填i32
是因为Vec::new
它创建的是一个空的Vector
,里面没有元素,又因为没有前后文供Rust推断,所以Rust就推断不出来这个变量里的元素是什么类型的,就会报错。所以这里需要显式声明。如果有前后文供Rust推断,Rust就能够自行判断Vector
里的元素类型。
而在一般情况下,会使用指定初始值的方式来创建Vector
,这样的方式就可以使用Veec!
这个宏。如下例:
fn main() { let v = vec![1, 2, 3];
}
这里就不需要显式声明Vector
里的元素类型了,因为Rust编译器根据初始值1、2、3推断出了元素类型是i32
。
8.1.2. 如何更新Vector
1. 添加元素
向Vector里添加元素使用push
这个方法。如下例:
fn main() { let mut v = Vec::new(); v.push(1);
}
- 注意,向
Vector
里添加元素的前提是这个Vector
是可变变量,所以在声明的时候需要mut
关键字。 - 这里的
let mut v = Vec::new();
也没有显式声明元素类型,但是Rust编译器通过下文向Vector
里添加1
的操作推断出了元素类型是i32
。
2. 删除Vector
与任何其他的struct结构体一样,当Vector
离开作用域后,它和它里面的元素就会被清理掉。
3. 读取Vector的元素
一共有两种方式可以应用Vector
里面的值,一种是使用索引,一种是使用get
方法。如下例:一个Vector
,里面存有1 2 3 4 5,访问并打印出第三个元素。
fn main() { let v = vec![1, 2, 3, 4, 5]; let third = &v[2];//索引 println!("The third element is {}", third); match v.get(2) { //get方法加matchSome(third) => println!("The third element is {}", third), None => println!("There is no third element."), };
}
let third = &v[2];
是使用索引的方式,访问第三个元素就是索引2的位置,所以[]
内写2。而在变量v
前加上&
表示是引用。v.get(2)
就是使用get
方法来实现读取的,但由于get
的返回值是Option
这个枚举类型(在6.2. Option枚举中讲过,这里不再赘述),所以要使用match
表达式(在6.3. 控制流运算符-match中讲过match
)来解包。
如果能从这个索引取到值,那么就会把这个索引下的值绑定给third
这个变量,然后在后面的代码块中输出。如果不能,返回的是None
这个变体,就会打印"There is no third element."。
这两者的实现方法比较不同,效果是一样的。但如果是非法的访问(比如访问的索引越界了,超过了实际Vector
的长度),两种将会有一些区别。
先试试使用索引:
fn main() {let v = vec![1, 2, 3, 4, 5];let third = &v[100]; //索引100越界了println!("The third element is {}", third);
}
输出:
index out of bounds: the len is 5 but the index is 100
程序触发了panic!
,终止了程序执行,警告了索引越界。
再试试使用get
:
fn main() {let v = vec![1, 2, 3, 4, 5];match v.get(100) { //索引100越界了Some(third) => println!("The third element is {}", third), None => println!("There is no third element."), };
}
输出:
There is no third element.
因为get
函数不能从索引100上获取东西,所以它就会返回None
。
在写代码时,就需要确定自己的需求。遇到越界的情况,想要直接触发panic!
结束程序就用所以找元素,其余的情况用get
函数最好。
8.1.3. 所有权和借用规则
还记得在4.2. 所有权规则、内存与分配中讲的借用规则吗?同一个作用域内不能同时有可变和不可变引用。这个规则在Vector
依然是适用的。看个例子:
fn main() {let mut v = vec![1, 2, 3, 4, 5];let first = &v[0];v.push(6);println!("The first element is {}", first);
}
输出:
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable--> src/main.rs:4:5|
3 | let first = &v[0];| - immutable borrow occurs here
4 | v.push(6);| ^^^^^^^^^ mutable borrow occurs here
5 | println!("The first element is {}", first);| ----- immutable borrow later used here
push
函数的参数是&mut self, value: T
,&mut
表示push
函数会把传进来的变量作为可变引用来处理。在例子中就是v
在这里有一个可变的引用。let first = &v[0];
这里的first
是v
的不可变引用,两者又在同一个作用域下,所以会报错println!
会把传进去的变量作为不可变引用。
在这个作用域内,同时出现了可变和不可变引用,所以程序会报错。
但有人可能会疑惑——push
函数是往Vector
的后面加东西,而前面的元素不会受影响,为什么Rust要搞这么麻烦的设计?
这是因为在内存中Vector
的元素是连续存储的,如果往后面加一个元素,正好又有东西占用了后面的内存,腾不出地方放新的元素,系统就得重新分配内存,找个足够大的地方来放置添加了元素之后的Vector
。这样的话,原来的那块内存就会被释放或者重新分配掉,但引用仍然会指向原先的那内存地址,造成悬空引用(在4.4. 引用与借用中有讲)
8.1.3. 遍历Vector里的值
使用for
循环是最常见的方法。如下例:
fn main() { let v = vec![1, 2, 3, 4, 5]; for i in &v { println!("{}", i); }
}
输出效果:
1
2
3
4
5
当然,如果想要在循环里修改元素也是可以的,只需要把v
声明成可变的,把&v
改成&mut v
即可:
fn main() { let mut v = vec![1, 2, 3, 4, 5]; for i in &mut v { *i += 10; } for i in v { println!("{}", i); }
}
注意:第四行的*i
前面之所以有个*
是因为i
在本质上是&mut i32
类型,存储的是指针而不是实际的i32
值,需要先解引用,使i
变为i32
类型获得实际的值才能进行加减操作。
输出效果:
11
12
13
14
15
相关文章:
【Rust自学】8.1. Vector
喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 8.1.0. 本章内容 第八章主要讲的是Rust中常见的集合。Rust中提供了很多集合类型的数据结构&…...
华为OD机试真题---服务器广播
华为OD机试中的“服务器广播”题目是一个经典的算法问题,通常涉及图论和连通分量的概念。以下是对该题目的详细解析: 一、题目描述 服务器之间可以通过网络进行连接,连接方式包括直接相连和间接连接。给出一个NN的数组(矩阵&…...
又一年。。。。。。
2024,浑浑噩噩的一年。 除了100以内的加减法(数据,数据,还是数据。。。。。。),似乎没做些什么。 脸盲症越来越重的,怕是哪天连自己都不认得自己的了。 看到什么,听到什…...
【JAVA高级篇教学】第六篇:Springboot实现WebSocket
在 Spring Boot 中对接 WebSocket 是一个常见的场景,通常用于实现实时通信。以下是一个完整的 WebSocket 集成步骤,包括服务端和客户端的实现。本期做个简单的测试用例。 目录 一、WebSocket 简介 1. 什么是 WebSocket? 2. WebSocket 的特…...
Kotlin在医疗大健康域的应用实例探究与编程剖析(下)
四、Kotlin医疗编程实例分析 4.1 移动医疗应用实例 4.1.1 患者健康监测应用 在当今数字化医疗时代,患者健康监测应用为人们提供了便捷的健康管理方式。利用Kotlin开发的患者健康监测应用,能够实时采集患者的各类生理数据,如心率、血压、血氧饱和度等,并通过直观的可视化…...
Oracle Dataguard(主库为 Oracle 11g 单节点)配置详解(3):配置备用数据库
Oracle Dataguard(主库为 Oracle 11g 单节点)配置详解(3):配置备用数据库 目录 Oracle Dataguard(主库为 Oracle 11g 单节点)配置详解(3):配置备用数据库一、…...
LeetCode算法题——移除元素
题目描述 给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作࿱…...
七大设计原则之开闭原则
目录 一、什么是开闭原则? 二、如何做到开闭原则? 1、面向接口或抽象类编程 2、依赖注入 3、单一职责原则 三、是不是为了满足开闭原则就要一味的追求代码的扩展性? 一、什么是开闭原则? 相信很多人都听说过这个原则&#x…...
【stm32+K210项目】基于K210与STM32协同工作的智能垃圾分类系统设计与实现(完整工程资料源码)
视频效果演示: 基于K210与STM32协同工作的智能垃圾分类系统设计与实现 目录: 目录 视频效果演示: 目录: 项目简介: 一、设计目的: 1.1 项目背景 1.2 设计意义: 二、硬件部分: 2.1 st…...
Ps:创建数据驱动的图像
在设计实践中,常常需要处理大量内容变化但设计格式统一的任务,例如批量生成名片、工作证、学生证、胸牌、奖状或证书甚至图册。这些工作如果逐一手动制作,不仅耗时费力,还容易出错。 为解决这一问题,Photoshop 提供了强…...
git的全通路线介绍
一、关系 1.git是代码版本管理工具,即可将项目切换到任意版本。 2.github与gitee是基于git技术构建的远程仓库网站。github是国外建立的,资源更丰富;gitee是国内建立的,免费功能更多。 3.gitlab与github类似,只不过…...
R1-3学习打卡
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 RNN心脏病识别 导入数据数据预处理标准化模型训练模型评估个人总结 import tensorflow as tfgpus tf.config.list_physical_devices("GPU")…...
Vue.js组件开发-实现无感刷新Token
在Vue.js应用中,实现无感刷新Token涉及到在用户的会话Token即将过期或已经过期时自动获取新的Token,而不影响用户的操作体验。需要通过拦截器(interceptors)来处理API请求,并在检测到Token过期或无效时自动进行刷新。 …...
可编辑31页PPT | 大数据湖仓一体解决方案
荐言分享:在当今数字化时代,大数据已成为企业决策和业务优化的关键驱动力。然而,传统的数据处理架构,如数据仓库和数据湖,各自存在局限性,难以满足企业对数据高效存储、灵活处理及实时分析的综合需求。因此…...
如何实现一个充满科技感的官网(二)
背景 在上一篇文章 《如何实现一个充满科技感的官网(一)》 中,我们初步了解了该官网的整体设计,并与大家探讨了它的视觉呈现和用户体验。 我们前期的内部设计偏向简洁,所以开始思考如何提升网站的整体设计感。这些尝…...
深度学习算法:从基础到实践
简介 深度学习作为人工智能领域的一个重要分支,近年来在多个领域取得了显著的成就。本文将从基础概念出发,探讨深度学习算法的核心原理,并介绍一些实际应用案例。 深度学习算法的核心概念 深度学习算法基于人工神经网络,通过构…...
等价和划分
例子:学生分组 假设我们有一个班级,班级里有10名学生,我们想要根据他们的年龄来分组。我们可以定义一个关系 ( R ) 在学生集合 ( A ) 上,其中 ( A {s_1, s_2, …, s_{10}} ),并且 ( s_i ) 和 ( s_j ) 之间有关系 ( R…...
电商项目-数据同步解决方案(三)商品上架同步更新ES索引库
一、 需求分析和业务逻辑 主要应用技术有:Feign远程调用, 消息队列-RabbitMQ ,分布式搜索引擎-ElasticSearch,Eureka,Canal 商品上架将商品的sku列表导入或者更新索引库。 数据监控微服务需要定义canal监听器&#x…...
MySQL数据库笔记——多版本并发控制MVCC
大家好,这里是Good Note,关注 公主号:Goodnote,本文详细介绍MySQL的并发控制:多版本并发控制MVCC。 文章目录 背景介绍数据库并发控制——锁机制悲观锁和乐观锁悲观锁乐观锁 数据库并发控制——MVCC 的引入MVCC 和锁机…...
【LLM综述】29种大模型Prompt Engineering技术
note 从零样本(Zero-shot)提示到最新进展的各种提示技术,包括推理和逻辑链(Chain-of-Thought, CoT)提示、自动链式思考(Auto-CoT)提示、自我一致性(Self-Consistency)提…...
MySQL高级关联查询与复杂关系的处理
在关系型数据库的操作中,复杂关联查询和多层次关系建模是非常重要的技能。无论是在数据分析、业务数据处理,还是在数据可视化等各个方面,处理多表数据关联都是不可或缺的部分。通过高效的关联查询,可以在不同表之间建立关系,查询并整合多张表的数据,避免数据冗余并提升查…...
URL Moniker API
1. urlmon 介绍 urlmon 是指 URL Moniker API,它是 Microsoft Windows 操作系统中的一部分,通常用于处理 URL 和相关的任务。urlmon.dll 是其动态链接库,提供了一系列函数和接口,主要用于以下目的: URL 分析和处理&a…...
单元测试3.0+ @RunWith(JMockit.class)+mock+Expectations
Jmockit使用笔记_基本功能使用Tested_Injectable_Mocked_Expectations_jmockit.class-CSDN博客 测试框架Jmockit集合junit使用 RunWith(JMockit.class) 写在测试案例类上的注解 Tested 在测试案例中,写在我们要测试的类上面, 一般用实现类 Injectable 在测试案例中声明…...
halcon中图像滤波分为空间域和频域两种方法
均值滤波是一种线性平滑滤波。基本思想是用某像素邻域几个像素的平均值代替此像素原来的灰度值。 高斯滤波是用某像素邻域几个像素的加权平均值代替此像素的原有灰度值。 总结:图像滤波分为空间域和频域两种方法。 空间域滤波主要是对像素的直接处理,它将…...
maxminddb地理信息库–C语言
原文地址:maxminddb地理信息库–C语言 – 无敌牛 欢迎参观我的个人博客:无敌牛 – 技术/著作/典籍/分享等 maxminddb 是一个 IP 的地理信息库,可以根据 IP 地址给出对应的地理位置信息。 下载离线库 maxminddb提供在线查询,也…...
Keil中的gcc
文章目录 一、IDE背后的命令1.1 IDE是什么1.2 IDE的背后是命令1.3 有两套主要的编译器 二、准备工作2.1 arm-linux-gcc和gcc是类似的2.2 Code::Blocks2.2.1 设置windows环境变量2.2.2 命令行示例 三、gcc编译过程详解3.1 程序编译4步骤3.2 gcc的使用方法3.2.1 gcc使用示例3.2.2…...
【Java数据结构】栈和队列相关算法
第一题:改变元素的序列 例1:若进栈序列为1,2,3,4,进栈过程中可以出栈,则下列不可能一个出栈序列(); A:1,4,3,…...
LoRA微调系列笔记
系列文章目录 第一章:LoRA微调系列笔记 第二章:Llama系列关键知识总结 第三章:LLaVA模型讲解与总结 文章目录 系列文章目录LoRA:Low-Rank Adaptation of Large Language Models目的:依据:优势:…...
Linux(Ubuntu)下ESP-IDF下载与安装完整流程(3)
接前一篇文章:Linux(Ubuntu)下ESP-IDF下载与安装完整流程(2) 本文主要看参考官网说明,如下: 快速入门 - ESP32-S3 - — ESP-IDF 编程指南 latest 文档 Linux 和 macOS 平台工具链的标准设置 - ESP32-S3 - — ESP-IDF 编程指南 latest 文档 一、安装准备 1. Linux用...
【C++】22___STL常用算法
目录 一、常用遍历算法 二、常用查找算法 2.1 find 2.2 其它查找算法 三、常用排序算法 3.1 sort 3.2 其它排序算法 四、拷贝 & 替换 4.1 copy 4.2 其它算法 五、常用的算数生成算法 5.1 accumulate 5.2 fill 六、常用集合算法 6.1 set_intersection 6…...
linux 批量替换文件指定字符串
启发:数据库连接串的用户名需要从sa修改为sasa find . -type f -name mssql.json -exec sed -i s/IDsa;/IDsasa;/g {}...
List接口(源码阅读)
文章目录 1.List接口常用方法1.代码2.结果 2.ArrayList底层机制1.结论2.ArrayList底层源码1.代码2.debug添加第一个元素1.进入2.elementData数组存储ArrayList的数据3.初始化为空数组4.首先确保使用size1来计算最小容量5.如果elementData为空,最小容量就是106.modCo…...
股市学习 seekingalpha tradingview
EMA EMA(Exponential Moving Average)是一种技术分析中常用的指标,用于平滑股价或其他资产价格的波动,以帮助分析价格走势的趋势和方向。EMA与简单移动平均(SMA)类似,但对最新价格的权重更大&a…...
用再生龙备份和还原操作系统(三)
续上篇《用再生龙备份和还原操作系统(二)》 三,用再生龙将镜像文件还原到硬盘 将再生龙工具盘、待还原系统的硬盘(与源盘一样大或更大)、镜像文件所在磁盘(如果是U盘,也可以后插)安…...
FaceFusion 从0开始本地部署,RTX4060
FaceFusion 从0开始本地部署指南 一、环境准备 1. 基础工具安装 1.1 Git 安装 使用管理员权限打开 PowerShell执行安装命令: winget install -e --id Git.Git验证安装: git --version1.2 FFmpeg 安装 使用管理员权限打开 PowerShell执行安装命令&…...
Swift Combine 学习(六):自定义 Publisher 和 Subscriber
Swift Combine 学习(一):Combine 初印象Swift Combine 学习(二):发布者 PublisherSwift Combine 学习(三):Subscription和 SubscriberSwift Combine 学习(四&…...
服务器网卡绑定mode和交换机的对应关系
互联网各领域资料分享专区(不定期更新): Sheet 模式类别 网卡绑定mode共有七种(0~6): bond0、bond1、bond2、bond3、bond4、bond5、bond6 mode详解 mode0 ,即:(balance-rr) Round-robin policy(平衡轮循环策略,需要配置交换机静态聚合) mode…...
【动手学轨迹预测】2.4 考虑地图拓扑关系的表征方法
上一节我们介绍了VectorNet提出了矢量化场景表征方法, 大幅提高了预测网络编码性能. 但是VectorNet对地图数据的编码是基于无向无权图的, 并没有考虑到地图的拓扑关系. 显然在预测中, 地图的拓扑关系应该被考虑到. 于是在VectorNet的基础上, LaneGCN提出一种将地图车道作为节点…...
ChatGLM3模型搭建(踩坑记录版)
参考 魔搭社区 https://zhuanlan.zhihu.com/p/720148240 智谱AI通用大模型:本地部署ChatGLM3-6B开源大模型 - 编程库 说明 搭建方式多篇文章结合着看; 模型下载强烈推荐魔塔社区下载ZhipuAI/chatglm3-6b; 官方github指定清华的模型没有…...
基于 Python Django 的花卉商城系统的研究与实现
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…...
Spring Boot 3 文件下载、多文件下载以及大文件分片下载、文件流处理、批量操作 和 分片技术
在 Spring Boot 3 中,实现文件下载、多文件下载以及大文件分片下载需要结合以下功能:文件流处理、批量操作 和 分片技术。以下是详细实现方案: 1. 单文件下载 基础的单文件下载实现,可以参考以下代码: GetMapping(&…...
什么是事件循环(Event Loop)?请谈谈它在 JavaScript 中的作用?
事件循环(Event Loop)是什么? 事件循环(Event Loop)是JavaScript运行时环境(如浏览器或Node.js)中的一个核心机制,用于处理异步操作和事件。 它负责协调代码的执行、事件的处理、以…...
Lua : Coroutine(协程)
Lua 协程(coroutines)是一种强大的控制结构,允许函数在执行过程中暂停并在稍后恢复。与线程不同,协程是非抢占式的,这意味着它们不会被操作系统调度,而是由程序显式地切换。协程在 Lua 中非常有用ÿ…...
【2024华为OD-E卷-200分-跳格子2】(题目+思路+JavaC++Python解析)
题目描述 在一个二维平面上,有一个 n x m 的网格,每个格子有一个非负整数。你从左上角 (0, 0) 开始,每次只能向右或向下移动,目标是到达右下角 (n-1, m-1)。 在移动过程中,你需要记录经过的格子中,最大数…...
【仓颉语言基础】语言概念、环境配置与语法解析
华为仓颉语言是一门专为分布式系统设计的现代编程语言,以简洁的语法和强大的分布式能力为核心,提供高效的资源管理和任务调度方案。本篇文章将带您从概念入手,逐步掌握环境配置与语法基础,为分布式开发奠定坚实基础。 文章目录 一…...
LeetCode - 初级算法 数组(删除排序数组中的重复项)
免责声明:本文来源于个人知识与公开资料,仅用于学术交流。 删除排序数组中的重复项 这篇文章讨论如何从一个非严格递增的数组 nums 中删除重复的元素,使每个元素只出现一次,并返回新数组的长度。因为数组是排序的,只要是相同的肯定是挨着的,所以我们需要遍历所有数组,然…...
SpringMVC进阶(自定义拦截器以及异常处理)
文章目录 1.自定义拦截器 1.基本介绍 1.说明2.自定义拦截器的三个方法3.流程图 2.快速入门 1.Myinterceptor01.java2.FurnHandler.java3.springDispatcherServlet-servlet.xml配置拦截器4.单元测试 3.拦截特定路径 1.拦截指定路径2.通配符配置路径 4.细节说明5.多个拦截器 1.执…...
2 秒杀系统架构
第一步 思考面临的问题和业务场景 秒杀系统面临的问题: 短时间内并发非常高,如果按照秒杀的并发做相应的承载会造成大量资源的浪费。第二解决超卖的问题。 第二步 思考目前的处境和解决方案 因为秒杀系统属于短时间内的高并发问题,我们不可能使用那么…...
C++如何遍历数组vector
在C中,vector是一个可变数组。那么怎么遍历它呢?我们以for循环为例(while循环,大家自己脑补)。 方法一: 基于范围的for循环,这是C11新引入的。 std::vector<int> v {1, 2, 3, 4, 5, 6…...
ubuntu非root用户操作root权限问题-virbox挂在共享文件夹
首先讲一下,virtuallbox 挂在文件夹,操作的时候总是需要root权限,比较费劲。 这一操作其实也正对着我们在Ubuntu上的操作。 前段时间我想在ubuntu正常用户下去操作i2c,也出现了类似的问题。 后来把正常的操作加到组里面也解决了类…...