【Rust自学】8.1. Vector
8.1 向量Vector8.1.0. 本章内容第八章主要讲的是 Rust 中常见的集合。Rust 提供了很多集合类型的数据结构这些集合可以包含很多值。但是第八章所讲的集合与数组和元组有所不同。第八章中的集合是存储在堆内存上而非栈内存上的这也意味着这些集合的数据大小无需在编译时就确定在运行时它们可以动态地变大或变小。本章主要会讲三种集合Vector本文、String 和 HashMap。8.1.1. 使用 Vector 存储多个值Vector这个类型的写法是VecT其中T代表泛型类型参数在实际使用时替换成自己需要的数据类型即可。Vector由标准库提供在Vector里可以存储多个相同类型的值它们在内存中是连续存放的。可以把它视为可扩展的数组。创建Vector可以使用Vec::new这个函数我们看个例子fn main() { let v: Veci32 Vec::new(); let v vec![1, 2, 3]; let v Vec::with_capacity(10); }let v: Veci32 Vec::new(): 使用Vec::new声明了一个元素类型为i32的Vector常用。let v vec![1, 2, 3]: 使用vec!宏创建带初始值的Vector。这里在声明时已经把1, 2, 3填进了向量。当然只使用vec![]不填内容也是可以的常用。let v Vec::with_capacity(10): 创建空 Vector但提前分配至少 10 个元素的容量。适合你已经知道大概要放多少元素能减少扩容次数提高性能。第一种方法Vec::new()需要显式声明类型为Veci32是因为Vec::new()创建的是一个空的Vector里面没有元素又因为这个例子里没有前后文供 Rust 推断所以 Rust 就推断不出来元素类型就会报错。如果有前后文供 Rust 推断Rust 就能够自行判断Vector里的元素类型。第二种方法vec![]就不需要显式声明元素类型了因为 Rust 编译器根据初始值推断出了元素类型是i32。8.1.2. 更新 Vector1. 添加元素向 Vector 末尾添加元素使用push方法。如下例fn main() { let mut v Vec::new(); v.push(1); }注意向Vector里添加元素的前提是这个Vector是可变变量所以在声明的时候需要mut关键字。这里的let mut v Vec::new();也没有显式声明元素类型但是 Rust 编译器通过下文向Vector里添加1的操作推断出了元素类型是i32。还有其他的一些添加元素的方法fn main() { let mut v Vec::new(); v.extend([1, 2, 3]); // 批量插入 v.insert(1, 99); // 在指定下标插入越界会 panic let mut a vec![1, 2, 3]; let mut b vec![4, 5, 6]; a.append(mut b); // 把 b 的所有元素移动到 ab 会变空 }2. 从 Vector 中删除元素pop()删除尾部元素并返回被Option包裹的值在 6.2. Option 枚举 中讲过。如果为空返回None。fn main() { let mut v vec![1, 2, 3]; let x v.pop(); // 返回 Some(3) }remove(index)删除指定位置的元素并返回它。后面的元素会前移。index越界会 panic。fn main() { let mut v vec![1, 2, 3]; let x v.remove(1); // 返回 2v 变为 [1, 3] }clear()清空所有元素。长度变成 0但容量仍然保留。fn main() { let mut v vec![1, 2, 3]; v.clear(); // v 现在是 [] }与任何其他的 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 方法加 match Some(third) println!(The third element is {}, third), None println!(There is no third element.), }; }let third v[2];使用索引访问位置 2 的元素第三个元素。前面的表示引用。v.get(2)使用get方法来读取。由于返回值是Option类型所以要使用match在 6.3. 控制流运算符-match 中讲过来解包。如果能取到值就会绑定给third并打印如果不能None就会打印 There is no third element.。这两种方法效果一样但对非法访问例如索引越界的处理不同。先试试使用索引非法访问fn main() { let v vec![1, 2, 3, 4, 5]; let third v[100]; // 索引 100 越界了 println!(The third element is {}, third); }输出thread main panicked at src/main.rs:3:19: index out of bounds: the len is 5 but the index is 100 note: run with RUST_BACKTRACE1 environment variable to display a backtrace程序触发了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 herepush函数的签名是mut self, value: Tmut表示push会把传进来的变量作为可变引用来处理。在例子中就是v在这里有一个可变引用。let first v[0];这里的first是v的不可变引用两者又在同一个作用域下所以会报错。println!会把传进去的变量作为不可变引用。在这个作用域内同时出现了可变和不可变引用所以程序会报错。但有人可能会疑惑——push是往Vector的后面加东西前面的元素不会受影响为什么 Rust 要搞这么麻烦的设计这是因为在内存中Vector的元素是连续存储的。如果往后面加一个元素正好又有东西占用了后面的内存腾不出地方放新的元素系统就得重新分配内存找个足够大的地方来放置添加了元素之后的Vector。这样的话原来的那块内存就会被释放或者重新分配掉但引用仍然会指向原先的内存地址造成悬空引用在 4.4. 引用与借用 中有讲。8.1.4. 遍历 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变为mut i32值才能进行加减操作。输出11 12 13 14 15

相关新闻

LoongRL技术解析:强化学习驱动的大模型长文本处理方案

LoongRL技术解析:强化学习驱动的大模型长文本处理方案

1. LoongRL技术全景解析:突破大模型长上下文推理的钥匙当我在处理一个涉及200页技术文档的问答任务时,传统大模型的表现让我彻底崩溃——要么丢失关键细节,要么生成完全偏离主题的答案。这正是LoongRL要解决的核心痛点:让AI真正理…

2026/7/23 18:49:02阅读更多 →
《硬盘突然打不开?别慌!专业数据恢复告诉你哪些操作千万别做》

《硬盘突然打不开?别慌!专业数据恢复告诉你哪些操作千万别做》

在日常使用电脑的过程中,很多人都会遇到硬盘突然打不开的情况。可能是双击盘符后长时间无响应,可能是提示无法访问,也可能是直接弹出错误对话框。遇到这种问题,大多数用户第一反应是反复尝试打开、重启电脑、插拔硬盘,…

2026/7/23 18:47:02阅读更多 →
CMU 15-213 CSAPP:并发编程与同步的艺术(Concurrent Programming)

CMU 15-213 CSAPP:并发编程与同步的艺术(Concurrent Programming)

写在前面:这是本系列系统级编程学习笔记的终章。 当我们的 Web 服务器终于能够通过网络响应一个客户端之后,新的问题接踵而至:如果同时有一万个人访问怎么办?并发编程(Concurrent Programming)是现代计算机…

2026/7/23 18:47:02阅读更多 →
【CTF-WEN-PHP】phps查看源代码并用双重URL编码绕过,admin编码为%25%36%31%25%36%34%25%36%44%25%36%39%25%36%45

【CTF-WEN-PHP】phps查看源代码并用双重URL编码绕过,admin编码为%25%36%31%25%36%34%25%36%44%25%36%39%25%36%45

题目 攻防世界-WEB-PHP2 https://adworld.xctf.org.cn/challenges/list 解题 访问网址 http://61.147.171.105:64825/index.phps admin.split().map(c > % c.charCodeAt(0).toString(16).toUpperCase()).join()%61%64%6D%69%6E%61%64%6D%69%6E.split().map(c > % …

2026/7/23 19:59:27阅读更多 →
告别低效记录!免费又好用的语音转文字软件深度评测,准确率高达98.7%

告别低效记录!免费又好用的语音转文字软件深度评测,准确率高达98.7%

你是否也曾在冗长的会议后,面对堆积如山的录音文件感到头疼?是否在学生时代,为了一字不差地记下老师的板书和口述而手忙脚乱?又或者,作为一名内容创作者,需要将大量的视频、音频采访素材快速转化为文字&…

2026/7/23 19:59:27阅读更多 →
【CTF-MISC-压缩包】脚本实现批量提取压缩包数据

【CTF-MISC-压缩包】脚本实现批量提取压缩包数据

题目 2024年春秋杯网络安全联赛冬季赛 - MISC - 压力大,写个脚本吧 https://www.ichunqiu.com/battalion?t1&r78931 解题思路 打开文件 发现一个压缩包一个txt文件 txt里有一串密文 RkdGR0ZHRkdGR0ZHRkdGR0ZHRkdGR0ZHRkdGR0ZHRkdGR0ZHRkdGR0ZHRkdGR0ZH…

2026/7/23 19:59:27阅读更多 →
AI电商头花主图生成:Stable Diffusion商业实践

AI电商头花主图生成:Stable Diffusion商业实践

1. 项目背景与核心价值这个头花产品商业化做图项目源于一个很实际的需求:如何在电商平台上用最低成本批量生成高质量产品展示图。作为从业十年的电商视觉设计师,我深知中小商家在商品主图制作上的痛点——请专业摄影师拍摄成本高,自己拍又难以…

2026/7/23 19:59:27阅读更多 →
[具身智能-629]:从单人闭环到五人协同:云端GPU与边缘专用芯片AI开发的本质鸿沟

[具身智能-629]:从单人闭环到五人协同:云端GPU与边缘专用芯片AI开发的本质鸿沟

很多AI开发者都有一个直观困惑:为什么在电脑、云端随便就能跑通的模型,移植到边缘嵌入式芯片后,bug层出不穷、精度断崖下跌、帧率死活不达标?核心答案并非算力差距,而是两套完全不同的AI工程体系、两种截然不同的研发模…

2026/7/23 19:59:27阅读更多 →
RAG(03)——高质量文本分块

RAG(03)——高质量文本分块

为什么你的RAG效果不佳? 核心痛点 LLM强大,Prompt精心调校,但答案仍不准确检索算法和Embedding已优化,却忽略分块(Chunking) 关键结论 “不恰当的分块给模型喂’坏数据”分块质量决定RAG性能的下限 分块的本质 分块的必要性 LM上下文长度限制-向量检索对语义完整性的…

2026/7/23 19:57:21阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/23 0:56:31阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/23 0:56:31阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/23 0:56:31阅读更多 →
Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具 【免费下载链接】chitchatter Secure peer-to-peer chat that is serverless, decentralized, and ephemeral 项目地址: https://gitcode.com/gh_mirrors/ch/chitchatter Chitchatter是一款革命性的安…

2026/7/23 0:00:28阅读更多 →
从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

更多请点击: https://intelliparadigm.com 第一章:从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表) 当AI副业主理人不再仅满足于单次服务交付,而是主动构建可复用、可裂变、可…

2026/7/23 0:00:28阅读更多 →
油泥处理设备哪里能买到

油泥处理设备哪里能买到

油泥处理设备哪里有?这是许多从事油田、炼化、清罐业务的从业者最关心的问题。根据河南三丰环保设备有限公司的行业经验,选购油泥处理设备的核心在于设备能否适配当地环保法规与原料特性,而非单纯看价格。该公司总经理王钦田先生指出&#xf…

2026/7/23 0:00:28阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/22 22:56:18阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/23 18:58:18阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/23 18:58:18阅读更多 →