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

喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)
请添加图片描述

10.6.1. 生命周期标注语法

  • 生命周期的标注并不会改变引用的生命周期长度。
  • 如果某个函数它制定了泛型生命周期参数,那么它就可以接收带有任何生命周期的引用。
  • 生命周期的标准主要是用于描述多个引用的生命周期之间的关系,但不影响生命周期。

生命周期的参数名称必须以'开头,通常是全小写且非常短的。很多开发者使用'a作为生命周期参数的名称。

生命周期的标注放在&符号后,在标注后边使用空格将标注和引用类型分开。

10.6.2. 生命周期标注例子

  • &i32:一个普通的引用
  • &'a i32:带有显式生命周期的引用,引用指向的类型就是i32
  • &'a mut i32:带有显式生命周期的可变引用

单个生命周期的标注本身没有意义,生命周期标注存在的意义是向Rust描述多个泛型生命周期之间的参数的关系。

以上一篇文章的代码为例:

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<'a>(x: &'a str, y: &'a str) -> &'a str {  if x.len() > y.len() {  x  } else {  y  }  
}

longest中的形参xy以及返回值的生命周期都是'a,这就意味着xy和返回值必须拥有“相同的”生命周期。

通过刚才的代码例也看到了,在函数签名中使用生命周期标注需要把泛型生命周期参数生命在<>里。这个签名会告诉Rust有这么一个生命周期'a,而xy和返回值的存活时间必须不短于'a

因为生命周期的标准主要是用于描述多个引用的生命周期之间的关系,但不影响生命周期。 所以这么写并不会影响实参的生命周期,这样写只是为借用检查器指出了一些可用于检查非法调用的一些约束而已。所以longest函数并不需要知道xy具体的存活时长,只需要某个作用域可以被用来代替'a,同时满足函数的签名约束即可。

如果函数引用它外部的代码,或者说它被外部的代码引用的时候,想单靠Rust本身来确定参数和返回值的生命周期几乎就是不可能的了。这样函数所使用的生命周期可能在每次调用中都发生变化。正是因此才需要手动对生命周期进行标注

在代码例中,当我们把具体的引用传入longest函数的时候,被用来代替'a的生命周期的作用域是哪一块呢?就是x的作用域和y的作用域所重叠的部分,也就是两者中生命周期较短的那个的生命周期。又因为返回值的生命周期也是'a,所以说返回的引用在x的作用域和y的作用域所重叠的部分都是有效的。

这就是为什么在前一篇文章和本文的前面对于“相同的”这个词都使用了引号标注,因为它并不是字面意义上的相同,而是指重叠的部分。

下面来看一下生命周期标注是如何对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 longest<'a>(x: &'a str, y: &'a str) -> &'a str {  if x.len() > y.len() {  x  } else {  y  }  
}

这样string1的作用域是从第2行到第8行,string2的作用域是从第4行到第7行。函数会寻找重叠的部分(或者说较短的那个生命周期),也就是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 longest<'a>(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行,那么返回值的作用域也该是第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的实际生命周期是取xy两个生命周期中较小的那个。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/66407.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML 显示器纯色亮点检测工具

HTML 显示器纯色亮点检测工具 相关资源文件已经打包成html等文件&#xff0c;可双击直接运行程序&#xff0c;且文章末尾已附上相关源码&#xff0c;以供大家学习交流&#xff0c;博主主页还有更多Html相关程序案例&#xff0c;秉着开源精神的想法&#xff0c;望大家喜欢&#…

服务器虚拟化:现代 IT 基础架构的核心技术

服务器虚拟化&#xff1a;现代 IT 基础架构的核心技术 随着云计算和大规模数据中心的快速发展&#xff0c;服务器虚拟化已成为现代 IT 基础架构中的核心技术。通过虚拟化&#xff0c;企业可以在同一台物理服务器上运行多个虚拟机&#xff08;VM&#xff09;&#xff0c;从而提…

晨辉面试抽签和评分管理系统之一:考生信息管理和编排

晨辉面试抽签和评分管理系统&#xff08;下载地址:www.chenhuisoft.cn&#xff09;是公务员招录面试、教师资格考试面试、企业招录面试等各类面试通用的考生编排、考生入场抽签、候考室倒计时管理、面试考官抽签、面试评分记录和成绩核算的面试全流程信息化管理软件。提供了考生…

PHP7和PHP8的最佳实践

php 7 和 php 8 的最佳实践包括&#xff1a;使用类型提示以避免运行时错误&#xff1b;利用命名空间组织代码并避免命名冲突&#xff1b;采用命名参数、联合类型等新特性增强可读性&#xff1b;用错误处理优雅地处理异常&#xff1b;关注性能优化&#xff0c;如避免全局变量和选…

Hadoop、Flink、Spark和Kafka

Hadoop、Flink、Spark和Kafka是大数据处理领域中的四个重要工具&#xff0c;它们在架构、数据处理方式以及性能等方面都存在区别。以下是具体分析&#xff1a; 架构 Hadoop&#xff1a;Hadoop的核心是HDFS&#xff08;Hadoop Distributed File System&#xff09;和MapReduce编…

C++和OpenGL实现3D游戏编程【2.1】——游戏基类Object的构建

欢迎来到zhooyu的专栏。 主页网址:【zhooyu】 专栏网址:【C++和OpenGL实现3D游戏编程】 🌟🌟🌟这里将通过一个OpenGL实现3D游戏编程实例教程,带大家深入学习OpenGL知识。知识无穷而人力有限,专题能够帮助您在有限的时间内快速了解并掌握OpenGL编程,深入掌握知识精华…

vue-i18n报错

1. 开发环境报错Uncaught (in promise) TypeError: ‘set’ on proxy: trap returned falsish for property ‘$t’ legacy需要设置为false const i18n createI18n({legacy: false,// 默认语言locale: lang,// 设置语言环境messages, })2. 打包配置tsc --noEmit时报错&#…

Vue 项目自动化部署:Coding + Jenkins + Nginx 实践分享

前言 本文详细记录如何使用 Coding (以 Jenkinsfile 为核心) 和 Nginx 部署 Vue 项目&#xff0c;包含完整流程、配置细节及注意事项&#xff0c;为开发者提供一个高效的实践参考。 准备工作 这里借用一个优秀的开源项目做演示&#xff1a;芋道源码/yudao-ui-admin-vue2。 以…

基于Arduino的FPV头部追踪相机系统

构建FPV头部追踪相机&#xff1a;让你置身于遥控车辆之中&#xff01; 在遥控车辆和模型飞行器的世界中&#xff0c;第一人称视角&#xff08;FPV&#xff09;体验一直是爱好者们追求的目标。通过FPV头部追踪相机&#xff0c;你可以像坐在车辆或飞行器内部一样&#xff0c;自由…

C# 服务生命周期:Singleton、Scoped、Transient

文章目录 1、概念:服务生命周期单例 (Singleton) :作用域 (Scoped) :瞬态 (Transient) : 2、对 Scoped 和 Transient 进一步辨析Scoped 生命周期Transient 生命周期选择哪种生命周期 1、概念:服务生命周期 单例 (Singleton) : 整个应用程序生命周期中只有一个实例被创建并共享…

【QT-QTableView实现鼠标悬浮(hover)行高亮显示+并设置表格样式】

1、自定义委托类 HoverDelegate hoverdelegate.h #ifndef HOVERDELEGATE_H #define HOVERDELEGATE_H#include <QObject> #include <QStyledItemDelegate>class hoverdelegate : public QStyledItemDelegate {Q_OBJECT // 添加 Q_OBJECT 宏public:explicit hoverde…

高并发场景下的秒杀系统架构设计与实现

引言 秒杀系统是一种高并发场景的典型应用&#xff0c;广泛存在于电商平台、抢票系统和促销活动中。秒杀活动的特点是短时间内吸引大量用户同时访问并尝试抢购商品&#xff0c;这对系统的高并发处理能力、稳定性和用户体验提出了极高的要求。 在秒杀系统中&#xff0c;常见的…

【渗透测试术语总结】

Top 渗透测试常用专业术语 相信大家和我一样&#xff0c;搞不清这些专业名词的区别&#xff0c;所以我来整理一下。 1. POC、EXP、Payload与Shellcode POC&#xff1a;全称 Proof of Concept &#xff0c;中文 概念验证 &#xff0c;常指一段漏洞证明的代码。 EXP&#xf…

企业网络性能监控

什么是网络性能监控 网络性能监控&#xff08;NPM&#xff09;是指对计算机网络的性能进行持续测量、分析和管理的过程&#xff0c;通过监控流量、延迟、数据包丢失、带宽利用率和正常运行时间等关键指标&#xff0c;确保网络高效、安全地运行&#xff0c;并将停机时间降至最低…

【Vim Masterclass 笔记05】第 4 章:Vim 的帮助系统与同步练习(L14+L15+L16)

文章目录 Section 4&#xff1a;The Vim Help System&#xff08;Vim 帮助系统&#xff09;S04L14 Getting Help1 打开帮助系统2 退出帮助系统3 查看具体命令的帮助文档4 查看帮助文档中的主题5 帮助文档间的上翻、下翻6 关于 linewise7 查看光标所在术语名词的帮助文档8 关于退…

Zookeeper是如何解决脑裂问题的?

大家好&#xff0c;我是锋哥。今天分享关于【Zookeeper是如何解决脑裂问题的?】面试题。希望对大家有帮助&#xff1b; Zookeeper是如何解决脑裂问题的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Zookeeper 通过一系列的机制来防止和解决脑裂&#xff08;sp…

【C++】const关键字_运算符重载_继承

目录 Const关键字 常量 常量指针 参数传递 返回值 成员函数 const作用域 运算符重载 继承 继承同名静态成员函数 构造和析构的调用顺序 多重继承 菱形继承&#xff08;二义性&#xff09; 虚继承的工作原理 友元 常&#xff08;成员&#xff09;函数 Const关键字…

QT-窗口嵌入外部exe

窗口类&#xff1a; #pragma once #include <QApplication> #include <QWidget> #include <QVBoxLayout> #include <QProcess> #include <QTimer> #include <QDebug> #include <Windows.h> #include <QWindow> #include <…

Java(day4)

二维数组 静态初始化 动态初始化 练习 public class test1 {public static void main(String[]args){int arr[][]{{22,66,44},{77,33,88},{25,45,65},{11,66,99}};int sum0;for(int i0;i<arr.length;i){int a0;for(int j0;j<arr[i].length;j){sumarr[i][j];aarr[i][j];…

「Mac畅玩鸿蒙与硬件52」UI互动应用篇29 - 模拟火车票查询系统

本篇教程将实现一个模拟火车票查询系统&#xff0c;通过输入条件筛选车次信息&#xff0c;并展示动态筛选结果&#xff0c;学习事件处理、状态管理和界面展示的综合开发技巧。 关键词 条件筛选动态数据展示状态管理UI交互查询系统 一、功能说明 模拟火车票查询系统包含以下功…