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

发布时间:2026/9/14 11:42:23

【Rust自学】10.6. 生命周期 Pt.2:生命周期的语法与例子 10.6 生命周期 Pt.2生命周期的语法与例子10.6.1. 生命周期标注语法标注生命周期并不会改变引用存活多久。如果某个函数指定了泛型生命周期参数那么它可以接收带有任何生命周期的引用。生命周期标注主要用于描述多个引用的生命周期之间的关系但它们本身并不影响生命周期。生命周期参数名必须以开头通常是全小写且非常短。很多开发者使用a作为生命周期参数名。生命周期标注放在符号后面并在标注与引用类型之间用空格隔开。10.6.2. 生命周期标注例子i32一个普通引用a i32带有显式生命周期的引用被引用的类型是i32a mut i32带有显式生命周期的可变引用单个生命周期标注本身没有意义。生命周期标注的目的是向 Rust 描述多个泛型生命周期之间的关系。以 10.5 生命周期 Pt.1生命周期的定义与意义、借用检查器与泛型生命周期 的代码为例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 } }longest中参数x、参数y以及返回值的生命周期都是a这意味着x、y和返回值必须拥有“相同”的生命周期。从上面的例子也可以看出在函数签名中使用生命周期标注时必须把泛型生命周期参数声明在里。这个签名告诉 Rust存在一个生命周期a并且x、y和返回值必须至少活得和a一样长。因为生命周期标注主要用于描述多个引用的生命周期之间的关系但它们本身并不影响生命周期所以这样写并不会改变实参的生命周期。它只是给借用检查器提供了一些可用于检测非法调用的约束。因此longest函数并不需要知道x和y到底活多久它只需要某个作用域可以用来代替a同时满足函数签名的约束即可。当函数引用外部代码或被外部代码引用时几乎不可能单靠 Rust 编译器确定参数和返回值的生命周期。这样的函数所使用的生命周期可能在每次调用时都会变化。这正是有时需要手动标注生命周期的原因。在示例代码中当我们把具体引用传入longest函数时用来代替a的作用域是哪一块呢就是x和y作用域的重叠部分换句话说是两者中较短的那个生命周期。又因为返回值也有生命周期a所以返回的引用在x和y作用域的重叠部分中保持有效。这就是为什么在 10.5 生命周期 Pt.1生命周期的定义与意义、借用检查器与泛型生命周期 以及本文前面都把“相同”一词放在引号里它并不是字面意义上完全相同的生命周期而是指重叠的部分。接下来看看生命周期标注如何约束对longest的调用。如果我们修改上面的例子让string1有不同的作用域并把string2改成String会发生什么fn main() { let string1 String::from(abcd); { let string2 String::from(xyz); let result longest(string1.as_str(), string2.as_str()); println!(The longest string is {result}); } } fn longesta(x: a str, y: a str) - a str { if x.len() y.len() { x } else { y } }这里string1的作用域是从第 2 行到第 8 行string2的作用域是从第 4 行到第 7 行。把它们传入longest时函数会寻找重叠部分——或者说较短的那个生命周期——也就是string2的作用域从第 4 行到第 7 行。因此a所代表的作用域是从第 4 行到第 7 行。result在内部作用域中有效也就是直到第 7 行的结束花括号为止所以代码在a范围内仍然有效。如果我改的是result的作用域呢fn main() { let string1 String::from(abcd); let result; { let string2 String::from(xyz); result longest(string1.as_str(), string2.as_str()); } println!(The longest string is {result}); } fn longesta(x: a str, y: a str) - a str { if x.len() y.len() { x } else { y } }在这种情况下string1的作用域是从第 2 行到第 9 行string2的作用域是从第 5 行到第 7 行。把它们传入longest时函数会寻找重叠部分——或者说较短的那个生命周期——也就是string2的作用域从第 5 行到第 7 行。因此函数的泛型生命周期参数a指的是从第 5 行到第 7 行的作用域返回值也应该有同样的作用域。然而接收返回值的result变量实际从第 3 行活到第 9 行超出了a所代表的作用域所以程序会报错error[E0597]: string2 does not live long enough -- src/main.rs:6:44 | 5 | let string2 String::from(xyz); | ------- binding string2 declared here 6 | result longest(string1.as_str(), string2.as_str()); | ^^^^^^^ borrowed value does not live long enough 7 | } | - string2 dropped here while still borrowed 8 | println!(The longest string is {result}); | ------ borrow later used here编译器说string2活得不够长。为了保证第 8 行打印的result有效string2必须一直保持有效直到外部作用域结束。因为函数参数和返回值使用了相同的生命周期Rust 才能指出这个问题。让我们再重复一遍本文最重要的一点a所代表的实际生命周期是x和y两个生命周期中较短的那个。
延伸阅读

更多相关文章

2026/9/13 7:24:14

手把手教你搞定研0第一次组会

家人们,研0第一次组会是不是紧张到抠手?怕文献读不对,PPT做不好,一开口就挨批?我当时也是。后来回头想,组会其实没那么可怕,只是因为没人提前告诉我该准备什么。今天就手把手教你搞定研0第一次组…

2026/9/6 17:23:46

【Rust自学】11.1. 编写和运行测试

11.1 编写和运行测试 11.1.1. 什么是测试 在Rust里,测试就是一个函数,用于验证非测试代码的行为是否符合预期。 一个测试函数通常执行三个操作: - 准备(Arrange)数据/状态 - 运行(Act)被测试的代码 - 断言(Assert)结果 这三个操作在有些语…

2026/9/13 10:51:23

【Rust自学】11.2. 断言(Assert)

11.2 断言(Assert) 11.2.1. 使用assert!宏检查测试结果 assert!宏来自标准库,用于判断某个条件是否为true。它接收一个返回类型为布尔值的表达式: - 当assert!内的值为true时,测试通过,assert!也不会做多余的操作。 - 当assert!…

2026/9/14 11:39:30

基于Java Swing的股票交易模拟系统:从订单队列到JDBC事务的完整实践

简介:面向数据结构课程设计而整理的Java实战项目,实现了一款基于Swing的股票交易模拟系统,覆盖行情实时展示、系统管理、账户管理、模拟交易、技术指标与策略分析等完整功能模块,适合计算机专业学生用于课程设计、毕业设计或Java …

2026/9/14 11:39:30

C#实现测绘后方交会坐标解算与精度验证

简介:本资源是一个基于C#开发的测绘专业后方交会计算程序,面向测绘工程学生、测量技术人员及C#初学者,解决未知点坐标解算这一典型测量问题。程序完整实现了数据输入、方位角转换、线性方程组求解、误差分析与结果输出等核心流程,…

2026/9/14 11:39:30

Three.js粒子特效实战:从核心原理到网页落地与性能优化

简介:基于Three.js的粒子特效网页设计源码,面向前端开发者和三维可视化初学者,演示如何用JavaScript与CSS构建动态粒子系统并集成3D模型,适用于个人网站、产品展示等需要增强视觉冲击力的场景。资源共41个文件,容量约6…

2026/9/14 11:39:30

Java并发核心:单例、阻塞队列、定时器与线程池全解析

Java并发进阶2:把单例、阻塞队列、定时器、线程池一次讲透并发编程这块,光看八股文和面试题是远远不够的,因为面试题告诉你的只是“结论”,而工程里的坑往往藏在“为什么”里。我见过不少人能背出线程池的七大参数,也能…

2026/9/14 11:39:30

专科生论文写作神器:8款实测有效的辅助工具推荐

1. 论文写作工具测评背景作为一名经历过毕业论文折磨的过来人,我深知专科生在论文写作过程中的痛点。从开题报告到文献综述,从格式排版到查重降重,每个环节都让没有科研经验的同学头疼不已。市面上号称能"一键生成论文"的工具层出不…

2026/9/14 11:34:29

Java SSM博客系统毕业设计实战:环境搭建、调试与高分答辩

简介:这是一套基于Java技术栈的高分毕业设计级博客系统,面向计算机专业本科生及Java初学者,适用于课程设计、期末大作业与毕设参考。系统采用SSM(SpringSpringMVCMyBatis)框架开发,后端以Java编写&#xff…

2026/9/14 2:17:50

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/14 0:03:22

KCF目标跟踪算法与OTB工程实现:毕业设计实战解析

简介:这是一份基于KCF核相关滤波算法、融合尺度池与抗遮挡处理的目标检测跟踪MATLAB完整源码,主要面向计算机相关专业准备毕业设计、课程设计或期末大作业的学生,也适合需要项目实战练习的初学者。源码在OTB数据集上完成验证,能够…

2026/9/14 0:03:22

语音情感识别实战:Keras实现LSTM、CNN、SVM与MLP多模型对比

简介:面向语音情感识别入门与进阶开发者,这份基于Keras的项目源码完整实现了LSTM、CNN、SVM、MLP四种模型,兼容Python3.8与Keras/TensorFlow2环境。压缩包内含49个文件,大小约70.31MB,主体包括Python脚本、yaml/json配…

2026/9/12 6:29:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/12 14:32:17

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/14 11:22:57

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码