首页/新闻资讯/正文详情

Rust学习文档(二)

发布时间:2026/11/15 20:44:03 来源:云帆数科 栏目:资讯中心
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/11/15 3:08:48

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/11/13 16:32:28

基于任务队列的多平台内容发布系统源码拆解
基于任务队列的多平台内容发布系统源码拆解

最近在整理一套多平台内容发布相关的代码时,我把整体结构重新梳理了一遍。 这类系统的目标很简单:把一篇文章从编辑状态,转换成适合蓝空GEO多个平台发布的形式,并把发布流程尽量自动化。一、问题背景平时写技术文章时,… · 2026/11/15 15:40:51

洋县低压电工证怎么报?官方报名入口全攻略,别再被中介坑了
洋县低压电工证怎么报?官方报名入口全攻略,别再被中介坑了

洋县低压电工证怎么报?官方报名入口全攻略,别再被中介坑了 你是不是也遇到过这种情况?在找工作或者想提升技能的时候,听说了洋县低压电工证的重要性,但一打听报名,不是被各种中介忽悠,就是不知道该去哪里?这不,我当初也和你一样,跑了好几家地方,最… · 2026/11/15 20:43:48

特种作业操作证冷库怎么考?上岗必备的避坑指南来了
特种作业操作证冷库怎么考?上岗必备的避坑指南来了

特种作业操作证冷库怎么考?上岗必备的避坑指南来了 怕考不过白交培训费?特种作业操作证冷库是很多冷库企业员工的“上岗必备”,但很多人因为不了解报考流程、考试内容、复审要求,结果花了钱还拿不到证,甚至考试挂科。今天咱们就从郑州项目现场管理员的角… · 2026/11/15 20:43:48

三级箱电工证怎么报名?南阳应届生必看的上岗指南
三级箱电工证怎么报名?南阳应届生必看的上岗指南

三级箱电工证怎么报名?南阳应届生必看的上岗指南 你是不是也像我一样,毕业之后到处找工作,但用人单位一开口就问“有没有三级箱电工证”?别急,今天我就用南阳卧龙区应届工程类毕业生的真实经历,带你一步步了解三级箱电工证怎么报名、怎么考、考完怎么用… · 2026/11/15 20:43:48

特级作业电工证怎么考 考过才能上岗 电子证书如何获取
特级作业电工证怎么考 考过才能上岗 电子证书如何获取

特级作业电工证怎么考 考过才能上岗 电子证书如何获取 急需特种作业证才能上岗找工作,这话不假,尤其是在建筑、电力、制造业这些行业,没有电工证、焊工证、高处作业证,连门都进不去。尤其是特级作业电工证,它不仅关系到你的职业资格,更是很多企业招聘… · 2026/11/15 20:43:48

土木行业电工证有用吗良心建议:外省证怎么转?全攻略来了
土木行业电工证有用吗良心建议:外省证怎么转?全攻略来了

土木行业电工证有用吗良心建议:外省证怎么转?全攻略来了 之前考的证在外省能不能转过来?这个问题,很多在工地打拼的朋友都问过。尤其是从一个省份换到另一个省份工作,证件能不能“跟着走”成了大家关心的头等大事。其实,根据郑州市应急管理局的最新规定… · 2026/11/15 20:43:48

沛县哪里学电工证好通过率揭秘
沛县哪里学电工证好通过率揭秘

沛县哪里学电工证好通过率揭秘 学历不高怕报不上名,别担心,今天就给你说说沛县电工证培训哪家强,还有通过率的 真实内幕 ,让你不走弯路、不花冤枉钱。 为什么学历不高也能报电工证?… · 2026/11/15 20:42:48

长春初级电工证怎么考?通过率揭秘全在这里
长春初级电工证怎么考?通过率揭秘全在这里

长春初级电工证怎么考?通过率揭秘全在这里 之前考的证在外省能不能转过来?这几乎是每个想从事电工工作的人都会问的问题。特别是那些在外地打拼多年、手里握着一张“外地电工证”的人,到了长春想继续干这一行,第一反应就是“我的证能用吗?”。今天我们就… · 2026/11/15 0:00:50

国内电工证报考条件与考试时间
国内电工证报考条件与考试时间

低压电工证怎么考?学历不高也能报名,官方报名入口全在这 你是不是经常听说“电工证是入行门槛”,但又担心自己学历不够、经验不足,根本报不了名?别急,今天就带你从零了解【国内电工证】的报考流程、考试内容,还有怎么在 官方报名入口… · 2026/11/15 0:00:50

电工作业时如何断电?电子证书到底能不能全国通用?
电工作业时如何断电?电子证书到底能不能全国通用?

电工作业时如何断电?电子证书到底能不能全国通用? 实操考试心里没底怕挂科,特别是电工作业时如何断电这一操作,不仅关系到你能不能拿到证书,更关系到以后能不能顺利上岗。很多人觉得这不过就是“断个电”,但其实这里面的门道可不少,稍有不慎就可能出错… · 2026/11/15 0:00:50

长春初级电工证怎么考?通过率揭秘全在这里
长春初级电工证怎么考?通过率揭秘全在这里

长春初级电工证怎么考?通过率揭秘全在这里 之前考的证在外省能不能转过来?这几乎是每个想从事电工工作的人都会问的问题。特别是那些在外地打拼多年、手里握着一张“外地电工证”的人,到了长春想继续干这一行,第一反应就是“我的证能用吗?”。今天我们就… · 2026/11/15 0:00:50

国内电工证报考条件与考试时间
国内电工证报考条件与考试时间

低压电工证怎么考?学历不高也能报名,官方报名入口全在这 你是不是经常听说“电工证是入行门槛”,但又担心自己学历不够、经验不足,根本报不了名?别急,今天就带你从零了解【国内电工证】的报考流程、考试内容,还有怎么在 官方报名入口… · 2026/11/15 0:00:50

电工作业时如何断电?电子证书到底能不能全国通用?
电工作业时如何断电?电子证书到底能不能全国通用?

电工作业时如何断电?电子证书到底能不能全国通用? 实操考试心里没底怕挂科,特别是电工作业时如何断电这一操作,不仅关系到你能不能拿到证书,更关系到以后能不能顺利上岗。很多人觉得这不过就是“断个电”,但其实这里面的门道可不少,稍有不慎就可能出错… · 2026/11/15 0:00:50

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

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

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

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

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

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

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码