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/10/14 16:57:19 阅读更多 →
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/10/14 16:57:03 阅读更多 →
计算机I/O系统四种控制方式详解:程序查询、中断、DMA与通道对比

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

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

2026/10/14 0:35:10 阅读更多 →

最新新闻

ZeroTermux 内置命令手册精讲:zcat 命令——不真正解压也能查看 gzip 压缩包内容

ZeroTermux 内置命令手册精讲:zcat 命令——不真正解压也能查看 gzip 压缩包内容

移动开发开发工具 【免费下载链接】ZeroTermux 项目地址: https://gitcode.com/GitHub_Trending/ze/ZeroTermux 点击查看 免费下载 本篇围绕 ZeroTermux 内置 Linux 命令手册(app/src/main/assets/cmd/zcat.md)展开,系统讲解 zca…

2026/10/15 18:12:24 阅读更多 →
基于CAN总线的温度采集与控制系统设计:抗干扰与主动报警实践

基于CAN总线的温度采集与控制系统设计:抗干扰与主动报警实践

简介:基于CAN总线的温度采集与控制系统完整工程包,面向嵌入式、STM32及CAN总线通信学习者,解决环境温度实时采集与上位机监控的实践需求。该工程以STM32为控制核心,结合DS18B20温度传感器与CAN收发节点,并配套上位机串…

2026/10/15 18:12:24 阅读更多 →
DeepSpec 实战指南:投机解码草稿模型的数据准备、训练与评估全流程

DeepSpec 实战指南:投机解码草稿模型的数据准备、训练与评估全流程

人工智能大模型预训练模型优化模型评测 【免费下载链接】DeepSpec DeepSpec: a full-stack codebase for training and evaluating speculative decoding algorithms 项目地址: https://gitcode.com/gh_mirrors/de/DeepSpec 点击查看 免费下载 DeepSpec 是一个面向…

2026/10/15 18:12:24 阅读更多 →
PCRE 8.45 正则库实战:编译、API 调用与性能优化指南

PCRE 8.45 正则库实战:编译、API 调用与性能优化指南

简介:pcre-8.45.tar.gz 是 PCRE(Perl Compatible Regular Expressions)库 8.45 版的官方源代码压缩包,面向需要在 CentOS 等 Linux 服务器环境中自行编译部署正则表达式引擎的开发者与运维人员。PCRE 以 C 语言编写,支…

2026/10/15 18:12:24 阅读更多 →
南大通用GBase 8a数据库压缩算法新老版本对照

南大通用GBase 8a数据库压缩算法新老版本对照

南大通用GBase 8a数据库(gbase database)旧算法配置参数中,可以控制使用算法的种类,而具体到某一算法,但只能采用默认的压缩级别,缺乏灵活性,也限制了算法在不同场景下发挥出最大效能。同时现在…

2026/10/15 18:12:24 阅读更多 →
IPMItool源码解析:从接口抽象到BMC诊断命令扩展

IPMItool源码解析:从接口抽象到BMC诊断命令扩展

简介:IPMItool 源码包是一份面向服务器运维工程师、系统管理员及BMC嵌入式开发者的开源工具源码,用于通过IPMI协议对BMC进行远程监控、传感器数据读取与电源管理。资源共171个文件,压缩包仅752KB,以50个头文件和49个C源文件为核心…

2026/10/15 18:11:23 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →