【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;望大家喜欢&#…

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

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

PHP7和PHP8的最佳实践

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

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;自由…

【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…

企业网络性能监控

什么是网络性能监控 网络性能监控&#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关键字…

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交互查询系统 一、功能说明 模拟火车票查询系统包含以下功…

Cherno C++学习笔记 P50 C++当中的动态库

在上一篇文章当中我们学习了C当中是如何使用静态库的&#xff0c;这一篇我们会讲一下如何使用动态库&#xff0c;并同样用GLFW这个已有的库来举例子。 有了静态库的经验&#xff0c;其实动态库就好理解和使用多了。这两者的区别是&#xff0c;静态链接发生在编译的时候&#x…

Linux-Ubuntu之裸机驱动最后一弹PWM控制显示亮度

Linux-Ubuntu之裸机驱动最后一弹PWM控制显示亮度 一&#xff0c; PWM实现原理二&#xff0c;软件实现三&#xff0c;正点原子裸机开发总结 一&#xff0c; PWM实现原理 PWM和学习51时候基本上一致&#xff0c;控制频率&#xff08;周期&#xff09;和占空比&#xff0c;51实验…

1.Python浅过(语法基础)

1.简介 Python是一种面向对象的解释型高级编程语言&#xff0c;是强类型的动态脚本语言。 解释型语言跨平台性比编译型语言&#xff08;如c语言&#xff09;好。 print("hello world")2.Bug,Debug 多看&#xff0c;多思考&#xff0c;多尝试、查资料、记录 3.prin…

Flutter:邀请海报,Widget转图片,保存相册

记录下&#xff0c;把页面红色区域内的内容&#xff0c;转成图片后保存到相册的功能 依赖 # 生成二维码 qr_flutter: ^4.1.0 # 保存图片 image_gallery_saver_plus: ^3.0.5view import package:demo/common/index.dart; import package:ducafe_ui_core/ducafe_ui_core.dart; i…

JVM实战—12.OOM的定位和解决

大纲 1.如何对系统的OOM异常进行监控和报警 2.如何在JVM内存溢出时自动dump内存快照 3.Metaspace区域内存溢出时应如何解决(OutOfMemoryError: Metaspace) 4.JVM栈内存溢出时应如何解决(StackOverflowError) 5.JVM堆内存溢出时应该如何解决(OutOfMemoryError: Java heap s…

科研绘图系列:R语言单细胞数据常见的可视化图形

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载导入数据数据预处理图1图2图3图4图5图6系统信息参考介绍 单细胞数据常见的可视化图形 因为本教程是单细胞数据,因此运行本画图脚本需要电脑的内存最少32Gb 加载…

公共数据授权运营机制建设(六大机制、存在问题、发展路径)

前言在国家战略部署下&#xff0c;学界和各地方政府从理论和实践两个层面积极探索公共数据授权运营机制。本期将从学理上剖析公共数据授权运营的基本内容&#xff0c;说明公共数据授权运营到底包括哪些内容&#xff0c;并且举例说明各地在公共数据授权运营机制建设方面的典型经…

CDP集成Hudi实战-spark shell

[〇]关于本文 本文主要解释spark shell操作Hudi表的案例 软件版本Hudi1.0.0Hadoop Version3.1.1.7.3.1.0-197Hive Version3.1.3000.7.3.1.0-197Spark Version3.4.1.7.3.1.0-197CDP7.3.1 [一]使用Spark-shell 1-配置hudi Jar包 [rootcdp73-1 ~]# for i in $(seq 1 6); do s…