【Rust自学】10.5. 生命周期 Pt.1:生命周期的定义与意义、借用检查器与泛型生命周期
10.5 生命周期 Pt.1生命周期的定义与意义、借用检查器与泛型生命周期10.5.1. 什么是生命周期Rust 中的每个引用都有自己的生命周期。生命周期的作用是让引用保持有效换句话说它就是引用保持有效的作用域。在大多数情况下生命周期是隐式的、可推断的。如果引用的生命周期可能以不同方式相互关联就必须手动标注生命周期。生命周期可以说是 Rust 与其他语言相比最与众不同的特征因此非常难学。10.5.2. 生命周期的存在意义生命周期存在的主要目的是避免悬空引用。这个概念在 4.4. 引用与借用 中已经讨论过这里重复一下之前的解释在使用指针时非常容易触发一种叫做悬空指针Dangling Pointer的错误。其定义如下一个指针引用了内存中的某个地址而这块内存可能已经被释放并重新分配给其他人使用。如果你引用了某些数据Rust 编译器会保证在引用离开作用域之前数据不会离开作用域。这就是 Rust 确保悬空引用永远不会出现的方式。看这个例子fn main() { let r; { // 小花括号 let x 5; r x; } println!({}, r); }在这个例子中先声明了r但没有初始化。目的是让r存在于小花括号外见注释位置的作用域中。当然Rust 没有Null值所以在初始化之前不能使用r。在小花括号内声明了变量x并赋值为5。下一行把x的引用赋给了r。在那个小花括号作用域结束之后在外面打印了r。这段代码是无效的因为打印r时x已经走出作用域并被销毁了。所以r的值——也就是x所引用的内存地址——现在指向的是已经被释放的内存它所指向的数据也不再是x。这就造成了悬空引用因此编译器会报错。输出error[E0597]: x does not live long enough -- src/main.rs:5:7 | 4 | let x 5; | - binding x declared here 5 | r x; | ^^ borrowed value does not live long enough 6 | } | - x dropped here while still borrowed 7 | println!({}, r); | - borrow later used here报错信息说借用的值活得不够长。这是因为内部花括号作用域结束时x走出了作用域但r有更大的作用域并可以继续使用。为了保证程序安全此时任何基于r的操作都无法正确运行。Rust 通过借用检查器来检查代码是否合法。10.5.3. 借用检查器借用检查器通过比较作用域来判断所有借用是否合法。在上面的例子中借用检查器发现r是对x的引用但r的存活时间比x更长因此会报错。怎么解决这个问题呢很简单让x至少活得和r一样长。fn main() { let x 5; let r x; println!({}, r); }在这种情况下x从第 2 行活到第 5 行r从第 3 行活到第 5 行。因此x的生命周期完全覆盖了r的生命周期程序不会报错。10.5.4. 函数中的泛型生命周期看这个例子fn main() { let string1 String::from(abcd); let string2 xyz; let result longest(string1.as_str(), string2); println!(The longest string is {result}); } fn longest(x: str, y: str) - str { if x.len() y.len() { x } else { y } }string1是String而string2是字符串切片str。这两个值被传入longest函数string1需要先转换成str然后打印返回值。longest的逻辑是比较两个输入参数并返回较长的那个。输出error[E0106]: missing lifetime specifier -- src/main.rs:9:33 | 9 | fn longest(x: str, y: str) - str { | ---- ---- ^ expected named lifetime parameter | help: this functions return type contains a borrowed value, but the signature does not say whether it is borrowed from x or y help: consider introducing a named lifetime parameter | 9 | fn longesta(x: a str, y: a str) - a str { | 错误说缺少生命周期标注更具体地说是返回类型缺少生命周期参数。正如help文本所说函数的返回类型包含一个借用值但函数签名没有说明这个借用值来自x还是来自y。考虑引入一个命名生命周期参数。再看这个函数fn longest(x: str, y: str) - str { if x.len() y.len() { x } else { y } }很明显这个函数的返回值要么是x要么是y但无法预先知道是哪一个。如果只看这个函数本身两个输入参数x和y的具体生命周期也是未知的。所以与前面的例子不同我们无法通过比较作用域来判断返回的引用是否会一直有效。借用检查器也做不到因为它不知道返回类型的生命周期是与x绑定还是与y绑定。实际上即使返回值是固定的这样写仍然会报错fn longest(x: str, y: str) - str { x }输出error[E0106]: missing lifetime specifier -- src/main.rs:9:33 | 9 | fn longest(x: str, y: str) - str { | ---- ---- ^ expected named lifetime parameter | help: this functions return type contains a borrowed value, but the signature does not say whether it is borrowed from x or y help: consider introducing a named lifetime parameter | 9 | fn longesta(x: a str, y: a str) - a str { | 编译器仍然无法判断因为函数签名没有表达返回类型中的借用值来自哪里。所以这与函数体内的逻辑无关完全与函数签名有关。该怎么改呢可以按照报错信息中的建议来改 help: this functions return type contains a borrowed value, but the signature does not say whether it is borrowed from x or y help: consider introducing a named lifetime parameter | 9 | fn longesta(x: a str, y: a str) - a str { | 既然它让我们添加泛型生命周期参数我们就添加一个fn longesta(x: a str, y: a str) - a str { if x.len() y.len() { x } else { y } }a表示一个名为a的生命周期。x、y和返回类型都使用生命周期a这意味着x、y和返回值的生命周期是相同的。“相同”这个说法并不完全精确因为main中x和y对应值的实际生命周期其实略有不同。这一点我们会在 10.6 生命周期 Pt.2生命周期的语法与例子 中讨论。现在看完整代码fn main() { let string1 String::from(abcd); let string2 xyz; let result longest(string1.as_str(), string2); println!(The longest string is {result}); } fn longesta(x: a str, y: a str) - a str { if x.len() y.len() { x } else { y } }输出The longest string is abcd

相关新闻

OpenClaw框架中的Self-Improving技能:AI Agent自主进化技术解析

OpenClaw框架中的Self-Improving技能:AI Agent自主进化技术解析

1. OpenClaw与Self-Improving技能概述OpenClaw作为新一代AI Agent开发框架,其核心价值在于提供了模块化的技能(Skill)体系。Self-Improving正是其中最引人注目的高级技能之一,它使AI Agent具备了持续进化的能力。不同于传统AI模型的静态表现,…

2026/10/18 4:43:26 阅读更多 →
FlexRay FIFO与消息处理机制深度解析:从双缓冲到实战配置

FlexRay FIFO与消息处理机制深度解析:从双缓冲到实战配置

1. 项目概述:为什么需要深入理解FlexRay的FIFO与消息处理? 在汽车电子和工业控制领域,当工程师们谈论高可靠性的实时通信时,FlexRay协议是一个绕不开的名字。它被设计用来满足下一代汽车网络对带宽、确定性和容错性的苛刻要求&…

2026/10/10 17:39:45 阅读更多 →
【Rust自学】10.6. 生命周期 Pt.2:生命周期的语法与例子

【Rust自学】10.6. 生命周期 Pt.2:生命周期的语法与例子

10.6 生命周期 Pt.2:生命周期的语法与例子 10.6.1. 生命周期标注语法 标注生命周期并不会改变引用存活多久。如果某个函数指定了泛型生命周期参数,那么它可以接收带有任何生命周期的引用。生命周期标注主要用于描述多个引用的生命周期之间的关系&#…

2026/10/12 17:14:28 阅读更多 →

最新新闻

TrueType字体解析:表目录、字符映射与轮廓还原

TrueType字体解析:表目录、字符映射与轮廓还原

简介:这份资源是一套TrueType字体格式解析类,面向从事游戏开发、图形设计、文本渲染等方向且需要深入处理字体文件的开发者。压缩包共2个文件,包含1个cpp实现文件和1个h头文件,整体仅42KB,代码量精简,便于直…

2026/10/18 5:41:43 阅读更多 →
同样标着五层瓦楞,怎么判断是不是“偷克重”的低配纸板?

同样标着五层瓦楞,怎么判断是不是“偷克重”的低配纸板?

同样标着五层瓦楞,怎么判断是不是“偷克重”的低配纸板?一、“偷克重”的常见手法五层瓦楞纸板由面纸、两张芯纸、两张瓦楞纸组成,部分厂家会在标注五层结构的前提下,降低各层原纸的克重,或是减薄芯纸、瓦楞纸的厚度。…

2026/10/18 5:41:43 阅读更多 →
JQuickExcel 流式导出配置:从阈值、窗口到临时文件的工程取舍

JQuickExcel 流式导出配置:从阈值、窗口到临时文件的工程取舍

JQuickExcel 流式导出配置:从阈值、窗口到临时文件的工程取舍 tags: #JQuickExcel #JavaExcel #开源 #POI #Excel工具 更多示例: JQuick-Excel 官网示例 https://www.jquick.org/jquick-excel/#demo-formulas0005 简介 我在处理大批量 Excel 导出时,…

2026/10/18 5:41:43 阅读更多 →
百考通资源平台:从海量题库到结构化数据的高效开发实践

百考通资源平台:从海量题库到结构化数据的高效开发实践

1. 为什么我说"百考通"不是又一个资料堆做开发这些年,我攒过的资料库、模板站、教程合集没有十套也有八套,但说实话,大部分都是"收藏即吃灰"。原因很简单:资源数量再多,跟实际开发需求对不上&…

2026/10/18 5:41:43 阅读更多 →
复合折射透镜CRL的VirtualLab Fusion建模与仿真:12 keV铍材料全流程

复合折射透镜CRL的VirtualLab Fusion建模与仿真:12 keV铍材料全流程

直接切入吧。过去这一年多我一直在跟X射线聚焦打交道,从最开始的苦等同步辐射机时,到后来在VirtualLab Fusion里把复合折射透镜的模型反复推到重来,算是把这条技术路线从原理到仿真再到实验数据闭环走了一遍。今天就把这套基于VirtualLab Fus…

2026/10/18 5:41:43 阅读更多 →
LabVIEW与VisionPro集成实战:从.NET直调到C#中间层方案

LabVIEW与VisionPro集成实战:从.NET直调到C#中间层方案

搞机器视觉集成这些年,"用LabVIEW做流程控制、拿VisionPro干算法活"的组合,我在不止一个项目里见过。LabVIEW 2020的图形化开发环境做交互界面、运动控制和数据流逻辑确实顺手,但真要处理复杂的视觉检测、精密定位、多模板匹配&…

2026/10/18 5:40:42 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 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/18 0:55:02 阅读更多 →
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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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/16 14:23:36 阅读更多 →