Rust学习文档(二)
目录02 所有权与借用2.1 什么是所有权OwnershipRust 为什么需要所有权所有权三条铁律作用域ScopeString 类型与栈/堆移动Move—— 核心机制克隆Clone—— 深拷贝Copy Trait —— 栈上拷贝函数传参与所有权转移函数返回值与所有权转移2.2 引用与借用References Borrowing问题所有权转移导致使用不便解决方案引用Reference可变引用Mutable Reference可变引用的限制 —— 同一时刻只能有一个不可变引用 vs 可变引用的互斥悬垂引用Dangling References—— Rust 在编译期防止引用规则总结2.3 切片Slices字符串切片字符串切片的危险性 —— UTF-8 边界函数参数中的字符串切片数组切片切片在内存中的表示2.4 所有权决策树速查学习目标检验02 所有权与借用2.1 什么是所有权OwnershipRust 为什么需要所有权语言内存管理方式问题C/C手动malloc/free忘记释放 → 内存泄漏重复释放 → 悬垂指针Java/Go垃圾回收GC运行时开销GC 暂停影响延迟Rust所有权系统编译期检查零运行时开销编译器保证安全所有权三条铁律1. Rust 中每一个值都有一个被称为其 所有者owner的变量2. 一次只能有一个所有者3. 当所有者离开作用域时这个值将被丢弃drop作用域Scope{ let s String::from(hello); // s 从这里开始有效 // 使用 s } // 作用域结束s 被丢弃drop内存自动释放String 类型与栈/堆let s1 String::from(hello); // 堆上分配可变长度 let s2 hello; // 栈上str 切片类型不可变 // String 由三部分组成存储在栈上 // - 指向堆数据的指针ptr // - 长度len // - 容量capacity移动Move—— 核心机制let s1 String::from(hello); let s2 s1; // s1 的所有权移动到 s2 // println!({s1}); // 编译错误s1 已失效 println!({s2}); // OK // 原因如果 s1 和 s2 都指向同一块堆内存 // 作用域结束时两者都会尝试释放 → 双重释放 → 内存不安全 // Rust 选择在移动时使原变量失效来避免此问题克隆Clone—— 深拷贝let s1 String::from(hello); let s2 s1.clone(); // 深拷贝堆数据独立 println!(s1 {s1}, s2 {s2}); // 两者都有效Copy Trait —— 栈上拷贝let x 5; let y x; // i32 实现了 Copy trait直接复制值栈拷贝 println!(x {x}, y {y}); // 两者都有效 // 实现 Copy trait 的类型全部存储在栈上 // - 所有整数类型i8, u32, usize 等 // - 所有浮点类型f32, f64 // - 布尔 bool // - 字符 char // - 元组仅当所有元素都是 Copy 时如 (i32, f64)函数传参与所有权转移fn main() { let s String::from(hello); takes_ownership(s); // s 已移动不可再使用 let x 5; makes_copy(x); // x 仍可用i32 是 Copy 类型 } fn takes_ownership(some_string: String) { println!({some_string}); } // some_string 离开作用域drop 被调用内存释放 fn makes_copy(some_integer: i32) { println!({some_integer}); } // some_integer 离开作用域无特殊操作函数返回值与所有权转移fn gives_ownership() - String { let some_string String::from(yours); some_string // 所有权移动给调用者 } fn takes_and_gives_back(a_string: String) - String { a_string // 原样返回所有权 } fn main() { let s1 gives_ownership(); let s2 String::from(hello); let s3 takes_and_gives_back(s2); // s2 已移动到函数内不可再用s3 拿到了返回的所有权 }2.2 引用与借用References Borrowing问题所有权转移导致使用不便fn calculate_length(s: String) - (String, usize) { let length s.len(); (s, length) // 必须同时返回所有权才能继续使用 } fn main() { let s1 String::from(hello); let (s2, len) calculate_length(s1); println!({} 的长度是 {}, s2, len); }解决方案引用Referencefn calculate_length(s: String) - usize { // 借用 String不获取所有权 s.len() } fn main() { let s1 String::from(hello); let len calculate_length(s1); // 创建指向 s1 的引用 println!({} 的长度是 {}, s1, len); // s1 仍然有效 }术语含义借用Borrowing创建一个引用的行为借用者拿到引用的函数/变量所有者原始变量始终拥有所有权可变引用Mutable Referencefn main() { let mut s String::from(hello); change(mut s); println!({s}); // hello, world } fn change(s: mut String) { s.push_str(, world); }可变引用的限制 —— 同一时刻只能有一个let mut s String::from(hello); let r1 mut s; // let r2 mut s; // 编译错误不能同时有两个可变引用 // println!({r1} {r2}); // 好处在编译期防止数据竞争data race // 数据竞争的三个条件Rust 在编译期全部排除 // 1. 两个或更多指针同时访问同一数据 // 2. 至少有一个指针在写入 // 3. 没有同步机制不可变引用 vs 可变引用的互斥let mut s String::from(hello); let r1 s; // 不可变引用 OK let r2 s; // 多个不可变引用 OK println!({r1} and {r2}); // r1, r2 的最后一次使用结束于此 let r3 mut s; // 可变引用 OKr1/r2 已不再使用 println!({r3}); // 关键NLLNon-Lexical Lifetimes非词法生命周期 // 作用域结束 ≠ 引用失效引用在最后一次使用后就失效了悬垂引用Dangling References—— Rust 在编译期防止// 这段代码在 Rust 中无法编译其他语言允许是常见 bug 源 fn dangle() - String { let s String::from(hello); s // 返回指向局部变量的引用 } // s 在此被 drop引用变成悬垂指针 // 编译器报错missing lifetime specifier // 正确写法直接返回所有权 fn no_dangle() - String { let s String::from(hello); s // 所有权移动出去不会有悬垂引用 }引用规则总结1. 在任意给定时间要么只能有一个可变引用要么只能有多个不可变引用2. 引用必须始终有效不能悬垂2.3 切片Slices字符串切片let s String::from(hello world); let hello s[0..5]; // hello let world s[6..11]; // world let whole s[..]; // 等价于 s[0..s.len()] let half s[..5]; // 等价于 s[0..5] // 切片类型str字符串字面量也是 str let s: str hello; // 类型是 str不可变字符串切片的危险性 —— UTF-8 边界let s String::from(你好); // let h s[0..1]; // 运行时 panic你 占 3 字节不是 1 字节 // 正确做法 let h s[0..3]; // 你3 字节函数参数中的字符串切片// 接受 String仅持有 String 引用时可用 fn first_word(s: String) - str { ... } // 接受 strString 和字符串字面量都能用更通用 fn first_word(s: str) - str { ... } fn main() { let s String::from(hello world); let word first_word(s); // 传入 String自动解引用为 str let word2 first_word(literal); // 传入 str 字面量也 OK }最佳实践函数参数优先使用str而非String更通用。数组切片let a [1, 2, 3, 4, 5]; let slice a[1..3]; // [i32] 类型值为 [2, 3]切片在内存中的表示String:┌─────────┬─────┬───────────┐│ ptr │ len │ capacity │ ← 栈上├─────────┼─────┼───────────┤│ │ │ ││ ┌───────────────────┐ ││ │ h e l l o \0 │ │ ← 堆上│ └───────────────────┘ │└─────────┼─────┼───────────┘str 切片┌─────┬─────┐│ ptr │ len │ ← 栈上没有 capacity└─────┴─────┘│└──→ 指向 String 堆数据的一部分2.4 所有权决策树速查需要传递数据给函数吗├── 函数需要修改数据│ └── 是 → 传 mut T可变引用└── 函数只需要读取├── 数据较小Copy 类型→ 传值自动复制└── 数据较大 → 传 T不可变引用需要从函数返回数据吗├── 在函数内创建的数据 → 直接返回所有权转移└── 调用方仍需持有 → 先 clone 再传不确定该用什么→ 默认用引用T编译器会告诉你何时需要所有权学习目标检验能清晰解释所有权三条铁律能区分移动和复制知道哪些类型是 Copy能解释为什么 Rust 要禁止悬垂引用能写出正确的可变引用和不可变引用组合理解 NLL非词法生命周期的含义能正确使用字符串切片str作为函数参数理解Stringvsstr的区别

相关新闻

Inline-Execute-PE开发解析:BOF编写与CobaltStrike Aggressor脚本集成

Inline-Execute-PE开发解析:BOF编写与CobaltStrike Aggressor脚本集成

Inline-Execute-PE开发解析:BOF编写与CobaltStrike Aggressor脚本集成 【免费下载链接】Inline-Execute-PE Execute unmanaged Windows executables in CobaltStrike Beacons 项目地址: https://gitcode.com/gh_mirrors/in/Inline-Execute-PE Inline-Execut…

2026/7/25 23:30:18 阅读更多 →
Adrenaline Todo应用教程:从零开始构建完整的GraphQL+React项目

Adrenaline Todo应用教程:从零开始构建完整的GraphQL+React项目

Adrenaline Todo应用教程:从零开始构建完整的GraphQLReact项目 【免费下载链接】adrenaline Simple Relay alternative 项目地址: https://gitcode.com/gh_mirrors/adre/adrenaline Adrenaline是一个轻量级的GraphQL中继替代方案,本教程将带您从零…

2026/7/25 23:30:18 阅读更多 →
计算机I/O系统四种控制方式详解:程序查询、中断、DMA与通道对比

计算机I/O系统四种控制方式详解:程序查询、中断、DMA与通道对比

计算机组成原理中的I/O系统是连接CPU与外部设备的关键桥梁,也是各类考试和面试的高频考点。这次我们聚焦I/O选择题专题,通过27道典型题目帮你快速掌握程序查询、程序中断、DMA和通道方式的核心区别与应用场景。 对于正在备考计算机组成原理的同学来说&a…

2026/7/25 23:29:17 阅读更多 →

最新新闻

V2EX Plus 开发者指南:从零开始构建浏览器扩展(Manifest V3)

V2EX Plus 开发者指南:从零开始构建浏览器扩展(Manifest V3)

V2EX Plus 开发者指南:从零开始构建浏览器扩展(Manifest V3) 【免费下载链接】v2ex-plus 可能是 v2ex 最好用的扩展 项目地址: https://gitcode.com/gh_mirrors/v2e/v2ex-plus V2EX Plus 是一款基于 Manifest V3 构建的 V2EX 浏览器扩…

2026/7/25 23:36:20 阅读更多 →
FDE实战一年:揭秘AI项目落地的“暗线”,小白程序员必备,助你成为业务翻译大师(收藏)

FDE实战一年:揭秘AI项目落地的“暗线”,小白程序员必备,助你成为业务翻译大师(收藏)

本文深入剖析了FDE(Forward Deployed Engineer)岗位的核心价值,强调AI项目成功的关键不在于技术本身,而在于能否深入理解企业业务,挖掘客户未明确表达的需求(暗线)。文章指出,FDE需要…

2026/7/25 23:36:20 阅读更多 →
从Java后端到AI应用开发:33岁转型踩坑8年终悟,2026年收藏这3类人慎重转行!

从Java后端到AI应用开发:33岁转型踩坑8年终悟,2026年收藏这3类人慎重转行!

作者分享8年Java后端转AI应用开发的经历,指出2026年AI应用开发前景广阔,但已非简单的接口调用。文章强调后端工程能力是大模型应用开发的关键,并针对后端转AI的3类人群提出警告。作者提出转型路径分为入门感知、深化理解、核心突破、工程落地…

2026/7/25 23:36:20 阅读更多 →
AI Agent工程:2026年技术分水岭与软件行业变革

AI Agent工程:2026年技术分水岭与软件行业变革

这次我们来看一个关于AI Agent技术趋势的重要观点。LangChain创始人Harrison Chase近期发出警告,认为2026年将成为“Agent工程”发展的关键分水岭,传统软件公司正面临前所未有的生存考验。这并非危言耸听,而是基于当前技术栈、开源生态和商业逻辑演变做出的判断。对于开发者…

2026/7/25 23:36:20 阅读更多 →
从零自制500W轴向磁通电机:电磁设计、绕线工艺与FOC驱动全解析

从零自制500W轴向磁通电机:电磁设计、绕线工艺与FOC驱动全解析

1. 先搞清楚“从零自制”到底意味着什么 如果你对“DIY一台500W电动自行车电机”感兴趣,那首先要明确一点:这里的“从零自制”和我们平时说的“组装一台电脑”或“焊接一个Arduino小车”有本质区别。它不是一个简单的零件拼装,而是涉及到 电磁设计、材料选择、精密加工、绕…

2026/7/25 23:36:20 阅读更多 →
如何用RxAutomaton构建登录流程:完整状态转换案例与代码实现

如何用RxAutomaton构建登录流程:完整状态转换案例与代码实现

如何用RxAutomaton构建登录流程:完整状态转换案例与代码实现 【免费下载链接】RxAutomaton 🤖 RxSwift State Machine, inspired by Redux and Elm. 项目地址: https://gitcode.com/gh_mirrors/rx/RxAutomaton RxAutomaton是一个基于RxSwift的状…

2026/7/25 23:35:20 阅读更多 →

日新闻

突破文档下载限制:kill-doc让你看到的都能保存

突破文档下载限制:kill-doc让你看到的都能保存

突破文档下载限制:kill-doc让你看到的都能保存 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档,但是相关网站浏览体验不好各种广告,各种登录验证,需要很多步骤才能下载文档,该脚本就是为了解决您的…

2026/7/25 0:00:35 阅读更多 →
C++ string类模拟实现:从深拷贝到内存管理的完整指南

C++ string类模拟实现:从深拷贝到内存管理的完整指南

1. 项目概述:为什么我们要“手撕”string类?在C的学习道路上,尤其是从C语言过渡到C的“初阶”阶段,string类绝对是一个绕不开的核心。标准库里的std::string用起来太方便了,、find、substr,几个操作符和函数…

2026/7/25 0:00:35 阅读更多 →
三角洲寻宝鼠工具:高效文件搜索与资源管理实战指南

三角洲寻宝鼠工具:高效文件搜索与资源管理实战指南

1. 先搞清楚“三角洲寻宝鼠”到底是什么工具从名称来看,“三角洲寻宝鼠”更像是一个资源查找或文件检索类工具,而不是游戏或娱乐软件。这类工具的核心价值在于帮助用户快速定位特定资源,比如文档、图片、压缩包或特定格式的文件。如果你经常需…

2026/7/25 0:00:35 阅读更多 →

周新闻

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

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

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

2026/7/25 5:08:22 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

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

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

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

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

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

2026/7/24 18:52:18 阅读更多 →

月新闻