【Rust】常见集合
目录
思维导图
一、Rust常用集合
1. Rust标准库中的集合概述
2. 常用集合类型
2.1 向量(Vector)
2.2 字符串(String)
2.3 哈希映射(Hash Map)
二、向量(Vec)
1. 向量的概述
2. 创建向量
3. 添加元素
4. 访问元素
5. 修改元素
6. 遍历向量
7. 使用枚举存储多种类型
8.向量的生命周期
三、字符串(String)
1.字符串的概述
2.字符串的创建
3.字符串的更新
4.字符串的连接
5.字符串的访问
四、哈希映射(HashMap)
1. 哈希映射的概述
2. 创建哈希映射
3. 插入哈希映射值
4. 访问哈希映射中的值
5. 遍历哈希映射
6. 哈希映射的所有权
7. 更新哈希映射
8. 哈希函数
思维导图
一、Rust常用集合
1. Rust标准库中的集合概述
Rust的标准库包含了一些非常有用的数据结构,统称为集合(Collections)。与其他数据类型不同,集合可以存储多个值。集合的数据存储在堆上,因此其大小可以在程序运行时动态变化,而不必在编译时确定。
2. 常用集合类型
在Rust中,常用的集合类型主要包括以下三种:
2.1 向量(Vector)
- 定义:向量是一种可以存储可变数量的值的集合。
- 特点:向量的元素在内存中是连续存储的,可以根据需要动态扩展或缩减。
- 使用场景:适合需要频繁插入、删除元素的场合,能够高效地处理动态数据。
2.2 字符串(String)
- 定义:字符串是字符的集合。
- 特点:Rust中的
String
类型支持动态大小,可以根据需要进行扩展。 - 使用场景:适用于需要处理文本数据的场合,如用户输入、文件读取等。
2.3 哈希映射(Hash Map)
- 定义:哈希映射是一种将特定键与值关联的数据结构,属于更通用的数据结构“映射”的一种实现。
- 特点:允许通过键快速访问对应的值,适合存储键值对数据。
- 使用场景:常用于需要快速查找、插入和删除的场合,如缓存实现、统计数据等。
二、向量(Vec)
1. 向量的概述
向量(Vec<T>
)是一种动态数组,可以存储多个相同类型的值。它在内存中是连续存储的,支持高效的随机访问和动态扩展。
2. 创建向量
1)空向量的创建:使用Vec::new()
函数创建一个空向量。例如:
fn main() {let v: Vec<i32> = Vec::new();[3]//这里需要类型注释,因为未插入任何值,Rust无法推断元素类型。
}
2) 带初始值的向量:使用vec!
宏创建带初始值的向量。例如:
fn main() {let v = vec![1, 2, 3];//Rust可以根据提供的初始值推断类型为Vec<i32>,因此类型注释不再必要。
}
3. 添加元素
添加元素:使用push
方法向向量中添加元素,必须将向量声明为可变(mutable):
fn main() {let mut v = Vec::new();v.push(5);v.push(6);
}
4. 访问元素
访问元素:可以通过索引或get
方法访问向量中的元素。值得注意的是,使用get
方法时,如果索引超出范围,返回None
,而使用索引直接访问则会导致程序崩溃。例如:
let third: &i32 = &v[2];
let third: Option<&i32> = v.get(2);
5. 修改元素
1)通过索引直接修改:通过索引可以直接访问并修改向量中的元素。需要注意的是,向量必须是可变的(mut
),并且索引必须在有效范围内。例如:
fn main() {let mut v = vec![1, 2, 3, 4];// 修改索引为 2 的元素v[2] = 100;println!("{:?}", v); // 输出: [1, 2, 100, 4]
}
2)通过get_mut方法修改:get_mut
方法返回一个 Option<&mut T>
,允许安全地修改元素。如果索引有效,则返回可变引用;如果索引无效,则返回 None
。例如:
fn main() {let mut v = vec![1, 2, 3, 4];// 获取索引为 2 的可变引用if let Some(elem) = v.get_mut(2) {*elem = 100; // 修改元素}println!("{:?}", v); // 输出: [1, 2, 100, 4]
}
6. 遍历向量
1)不可变遍历:使用for
循环遍历向量中的每个元素:
for i in &v {println!("{i}");
}
2)可变遍历:可以通过可变引用遍历并修改每个元素:
for i in &mut v {*i += 50;
}
7. 使用枚举存储多种类型
由于向量只能存储相同类型的值,可以使用枚举来存储不同类型的值。例如:
enum SpreadsheetCell {Int(i32),Float(f64),Text(String),
}
let row = vec![SpreadsheetCell::Int(3),SpreadsheetCell::Text(String::from("blue")),SpreadsheetCell::Float(10.12),
];
8.向量的生命周期
向量在超出作用域时会自动释放其内存,所有元素也会随之释放。例如:
{let v = vec![1, 2, 3, 4];
} // v 超出作用域并被释放
三、字符串(String)
1.字符串的概述
字符串(String
)是 UTF-8 编码的字符集合,支持动态扩展。Rust 的字符串类型包括 String
和字符串切片 &str
。
2.字符串的创建
通过String::new()
创建一个新的空字符串,或使用to_string()
和String::from()
方法从字符串字面量创建字符串。示例代码如下:
fn main() {let mut s = String::new();let data = "initial contents";let s1 = data.to_string();let s2 = String::from("initial contents");
}
3.字符串的更新
String
可以通过push_str
方法追加字符串切片,或使用push
方法添加单个字符。示例代码如下:
fn main() {let mut s = String::from("foo");s.push_str("bar");s.push('!'); //foobar!
}
4.字符串的连接
可以使用 +
操作符或format!
宏来连接字符串。使用 +操作符时,左侧字符串会被移动,示例代码如下:
fn main() {let s1 = String::from("Hello, ");[7][8]let s2 = String::from("world!");let s3 = s1 + &s2; // s1被移动,s2仍然有效
}
5.字符串的访问
Rust不支持直接通过索引访问字符串中的字符,需使用chars()
方法或bytes()
方法进行迭代。例如:
fn main() {let hello = "Здравствуйте";[7]for c in hello.chars() {println!("{c}");}
}
四、哈希映射(HashMap)
1. 哈希映射的概述
哈希映射(HashMap<K, V>
)是一种键值对集合,通过哈希函数将键映射到值。它允许通过键快速查找、插入和删除值。
2. 创建哈希映射
可以使用HashMap::new()
方法创建一个空的哈希映射。示例代码:
fn main() {use std::collections::HashMap;let mut scores = HashMap::new();
}
3. 插入哈希映射值
可以使用insert
方法添加元素。示例代码:
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
4. 访问哈希映射中的值
可以使用get
方法通过键访问对应的值,返回类型为Option<&V>
,如果键不存在,则返回None
。示例代码:
let score = scores.get(&team_name).copied().unwrap_or(0);
ps: 此程序通过调用 copied
来获取一个 Option<i32>
而不是 Option<&i32>
来处理 Option
,然后如果 scores
没有该键的条目,则调用 unwrap_or
将 score
设置为零。
5. 遍历哈希映射
可以使用for
循环遍历哈希映射中的每个键值对。示例代码:
for (key, value) in &scores {println!("{key}: {value}");
}
6. 哈希映射的所有权
对于实现了Copy
特性的类型(如i32
),值会被复制到哈希映射中;对于拥有所有权的类型(如String
),值会被移动到哈希映射中。示例代码:
fn main() {use std::collections::HashMap;let field_name = String::from("Favorite color");let field_value = String::from("Blue");let mut map = HashMap::new();map.insert(field_name, field_value);//此处将使field_name和field_value在插入后失效
}
7. 更新哈希映射
1)覆盖值:插入同一键的新值会替换旧值。示例代码:
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Blue"), 25);
//{"Blue": 25}
2)仅在键不存在时插入:使用entry
方法检查键是否存在,若不存在则插入新值。示例代码:
scores.entry(String::from("Yellow")).or_insert(50);
ps-1: entry
方法的返回值是一个名为 Entry
的枚举,它表示一个可能存在也可能不存在的值。
ps-2: Entry
上的 or_insert
方法被定义为:如果对应的 Entry
键存在,则返回该值的可变引用;如果不存在,则将参数插入作为该键的新值,并返回新值的可变引用。
8. 哈希函数
默认情况下,HashMap
使用名为SipHash的哈希函数,具有防止拒绝服务(DoS)攻击的能力。虽然其性能可能不如其他哈希算法,但在安全性和性能之间的权衡是值得的。
tips:
-
向量:常用操作包括创建(
Vec::new()
、vec![]
)、添加(push
)、访问(索引、get
)、修改(索引、get_mut)和遍历(for
循环)。 -
字符串:常用操作包括创建(
String::new()
、to_string()
)、更新(push_str
、push
)、连接(+
、format!
)和遍历(chars()
、bytes()
)。 -
哈希映射:常用操作包括创建(
HashMap::new()
)、插入(insert
)、访问(get
)、遍历(for
循环)和更新(entry
、or_insert
)。
相关文章:

【Rust】常见集合
目录 思维导图 一、Rust常用集合 1. Rust标准库中的集合概述 2. 常用集合类型 2.1 向量(Vector) 2.2 字符串(String) 2.3 哈希映射(Hash Map) 二、向量(Vec) 1. 向量的概述…...

SpiderFlow平台v0.5.0之引入selenium插件
引入selenium插件 首先到码云下载插件点击下载编辑到本地并导入到工作空间或安装到maven库在spider-flow/spider-flow-web/pom.xml中引入插件 <!-- 引入selenium插件 --> <dependency><groupId>org.spiderflow</groupId><artifactId>spider-…...
git push命令
git push 常用命令 1. 拉取远程仓库最新数据 使用 git fetch git fetch作用: 获取远程仓库的最新数据(包括分支、标签等),但不会修改本地工作目录。 结果: 仅更新远程分支(如 origin/main)的…...

洛谷P1161
开灯 - 洛谷 代码区: #include<stdio.h> int ans[2000005]{1}; //1为关 int main(){int n;scanf("%d",&n);double arry[n][2];//此处最好用双精度浮点数,单精度浮点数的精确度够高对于此题来说,第一次没全对就是因为精度…...
Python脚本自动发送电子邮件
要编写一个Python脚本来自动发送电子邮件,你可以使用smtplib库来处理SMTP协议,以及email库来构建邮件内容。 安装必要的库 通常情况下,smtplib和email库是Python标准库的一部分,因此不需要额外安装。如果你使用的是较旧的Python版…...

vscode的安装与使用
下载 地址:https://code.visualstudio.com/ 安装 修改安装路径(不要有中文) 点击下一步,创建桌面快捷方式,等待安装 安装中文插件 可以根据自己的需要安装python和Jupyter插件...

sparkRDD教程之必会的题目
1.前期准备 (1)看看上一期的博客,最好跟着上一期的博客把sparkRDD的基本命令给熟练掌握后,再来做这篇文章的任务。 上一期的博客:sparkRDD教程之基本命令-CSDN博客 (2)新建文件task6.scala …...

Unity 2d描边基于SpriteRender,高性能的描边解决方案
目标 以Unity默认渲染管线为例,打造不需要图片内边距,描边平滑,高性能的描边解决方案 前言 在2d游戏中经常需要给2d对象添加描边,来突出强调2d对象 当你去网上查找2d描边shader,移植到项目里面,大概率会…...

信凯科技业绩波动明显:毛利率远弱行业,资产负债率偏高
《港湾商业观察》施子夫 1月8日,深交所官网显示,浙江信凯科技集团股份有限公司(以下简称“信凯科技”)主板IPO提交注册。 自2022年递交上市申请,信凯科技的IPO之路已走过两年光景,尽管提交注册࿰…...
js基础---var与let的区别以及const的使用
js基础—var与let的区别以及const的使用 var与let的区别 在较旧的JavaScript,使用关键字var来声明变量,而不是let。var现在开发中一般不再使用它,只是我们可能再老版程序中看到它。let的出现为了解决var的一些问题。 var 声明存在以下三种问…...

用css和html制作太极图
目录 css相关参数介绍 边距 边框 伪元素选择器 太极图案例实现、 代码 效果 css相关参数介绍 边距 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>*{margin: 0;padding: 0;}div{width: …...

OJ12:160. 相交链表
目录 题目思路分析代码展示 题目 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 示例 1: 输入:intersectVal 8, listA [4,1,8,4,5], listB [5,…...
软件工程和项目管理领域 - CMMI 极简理解
CMMI 概述 CMMI 全称为 Capability Maturity Model Integration,即能力成熟度模型集成 CMMI 是由美国卡内基梅隆大学软件工程研究所(SEI)开发的一套综合性管理模型 CMMI 是一种用于评估和改进组织在软件开发和维护方面过程能力的国际标准 …...

C# 线程基础之 线程同步
线程同步的手段很多 lock 是通过内存索引块 0 1 切换 进行互斥的实现 互斥量 信号量 事件消息 其实意思就是 一个 标记量 通过这个标记 来进行类似的互斥手段 具体方式的分析 代码在后 1.互斥量 Mutex 作用 非常类似lock 一个Mutex 名称来代替 lock的引用对象 2.信号量 Semaph…...

[c语言日寄]c语言也有“回”字的多种写法——整数交换的三种方式
大家好啊,在今天的快乐刷题中,我们遇到了这样一道题目: 题目 写出 三种不同方式的 交换两个整数变量的 函数 交换变量的三种解法 常规方式 想要交换两个变量很简单,第一种方式就是新建一个临时变量,具体流程如下&…...

RocketMQ 知识速览
文章目录 一、消息队列对比二、RocketMQ 基础1. 消息模型2. 技术架构3. 消息类型4. 消费者类型5. 消费者分组和生产者分组 三、RocketMQ 高级1. 如何解决顺序消费和重复消费2. 如何实现分布式事务3. 如何解决消息堆积问题4. 如何保证高性能读写5. 刷盘机制 (topic 模…...
优化 Azure Synapse Dedicated SQL Pool中的 SQL 执行性能的经验方法
在 Azure Synapse Dedicated SQL Pool中优化 SQL 执行涉及了解底层体系结构(例如分布和分区)、查询优化(例如避免不必要的子查询和联接),以及利用具体化视图和 PolyBase 等工具进行高效数据加载。 1.有效使用分布和分…...
详解英语单词“pro bono”:公益服务的表达(中英双语)
中文版 详解英语单词“pro bono”:公益服务的表达 一、词义解释 “Pro bono” 是一个源自拉丁语的短语,完整表达为 “pro bono publico”,意思是“为了公众利益”(for the public good)。在现代英语中,它…...
16. C语言 字符串详解
本章目录: 前言C 字符串的基础概念字符串的定义字符串的内存表示 常见的字符串操作函数示例代码 深入探讨字符串长度计算strlen 与 sizeof 的区别 字符串操作的注意事项**1. 字符数组的大小**2. 字符数组和字符指针的区别3. 使用安全函数 字符串的遍历与格式化输出**遍历字符串…...

使用Buildroot开始嵌入式Linux系统之旅-3
文章目录 at91bootstrap操作教程修改at91bootstrap具体配置重新编译at91bootstrap U-Boot操作教程修改U-Boot具体配置重新编译U-Boot Linux Kernel操作教程修改Linux Kernel具体配置重新编译Linux Kernel buildroot操作进阶生成图形化软件模块依赖关系查看具体软件模块依赖关系…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...
stm32进入Infinite_Loop原因(因为有系统中断函数未自定义实现)
这是系统中断服务程序的默认处理汇编函数,如果我们没有定义实现某个中断函数,那么当stm32产生了该中断时,就会默认跑这里来了,所以我们打开了什么中断,一定要记得实现对应的系统中断函数,否则会进来一直循环…...
基于Java项目的Karate API测试
Karate 实现了可以只编写Feature 文件进行测试,但是对于熟悉Java语言的开发或是测试人员,可以通过编程方式集成 Karate 丰富的自动化和数据断言功能。 本篇快速介绍在Java Maven项目中编写和运行测试的示例。 创建Maven项目 最简单的创建项目的方式就是创建一个目录,里面…...