【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操作进阶生成图形化软件模块依赖关系查看具体软件模块依赖关系…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...