Rust编程(三)生命周期与异常处理
生命周期
生命周期,简而言之就是引用的有效作用域。在大多数时候,我们无需手动的声明生命周期,因为编译器可以自动进行推导。生命周期的主要作用是避免悬垂引用,它会导致程序引用了本不该引用的数据:
{let r;{let x = 5;r = &x;}println!("R:{}",r);
}
这种情况r就是悬垂指针,r是引用的x,但是x的生命周期是到大括号结束就结束了,所以下面再使用r时,r就是一个悬垂指针。避免悬垂指针的方法就是:确保被引用的变量的生命周期长于引用本身。
fn main() {let string1 = String::from("abcd");let string2 = "xyz";let result = longest(string1.as_str(), string2);//会报错,因为编译器不知道返回是x还是y,自然就没法对result进行生命周期分析println!("The longest string is {}", result);
}fn longest(x: &str, y: &str) -> &str {if x.len() > y.len() {x} else {y}
}
对于一些复杂情况,编译器无法自己推导出生命周期,就需要我们自己进行生命周期标注:
&i32 // 一个引用
&'a i32 // 具有显式生命周期的引用
&'a mut i32 // 具有显式生命周期的可变引用
生命周期标注不对代码的逻辑起到任何作用,它自身并不具有什么意义,因为生命周期的作用就是告诉编译器多个引用之间的关系。
标注后的longest函数:
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {//这里告诉编译器,x和y的生命周期要长于`a//然后将二者的生命周期统一设定为较短的那个的生命周期//这样就不管是返回x还是y,result的生命周期都是一样的if x.len() > y.len() {x} else {y}
}
当只与一个参数有关时,可以只标注一个的生命周期:
fn function<'a>(arg1:&'a mut String,arg2:& mut String) -> &'a mut String{return arg1;
}fn main(){let mut s1 : String = String::new();let mut s2 : String = String::new();let s3 = function(&mut s1,&mut s2);println!("s3:{}",s3);
}
生命周期问题只针对于引用,主要是为了解决引用/借用还在,被引用/借用的没了的情况,对于move就没有这么麻烦,一旦move,直接生命周期就重新计算了,与之前的变量就没关系了。
结构体也有生命周期的要求,结构体内部有引用,被引用的对象的生命周期要长于结构体对象的生命周期:
struct ImportantExcerpt<'a> {part: &'a str,
}fn main() {let novel1 = String::from("Call me Ishmael. Some years ago...");let first_sentence1 = novel1.split('.').next().expect("Could not find a '.'");let i = ImportantExcerpt {part: first_sentence1,}; //这种没有问题let i;{let novel2 = String::from("Call me Ishmael. Some years ago...");let first_sentence2 = novel2.split('.').next().expect("Could not find a '.'");i = ImportantExcerpt {part: first_sentence2,};}println!("{:?}",i); //这种就会报错,因为first_sentence2在大括号结束的时候生命周期已经结束了
}
函数情况下分为输入生命周期和输出生命周期,一些编译器可以推断出输入输出生命周期的情况,就不需要进行生命周期标注,编译器推断生命周期有三个规则:
-
每一个引用参数都会获得独自的生命周期
例如一个引用参数的函数就有一个生命周期标注: fn foo<'a>(x: &'a i32),两个引用参数的有两个生命周期标注:fn foo<'a, 'b>(x: &'a i32, y: &'b i32), 依此类推。 -
若只有一个输入生命周期(函数参数中只有一个引用类型),那么该生命周期会被赋给所有的输出生命周期,也就是所有返回值的生命周期都等于该输入生命周期
-
例如函数 fn foo(x: &i32) -> &i32,x 参数的生命周期会被自动赋给返回值 &i32,因此该函数等同于 fn foo<'a>(x: &'a i32) -> &'a i32
-
若存在多个输入生命周期,且其中一个是 &self 或 &mut self,则 &self 的生命周期被赋给所有的输出生命周期。拥有 &self 形式的参数,说明该函数是一个 方法,该规则让方法的使用便利度大幅提升。
更多关于生命周期的内容,请参考
函数返回/异常处理
Rust的函数返回为了解决是否有值的问题,引入了一个枚举类型Option,有值时返回Some(T),没值时返回None,再也不用绞尽脑汁如何思考返回-1或者None了。
enum Option<T> {Some(T),None,
}
Rust的异常分为可恢复异常Result,出了异常不直接崩溃,还可以根据异常的类别继续运行,类似于其他语言中函数返回了-1或者None。另一种是不可恢复异常panic,出了问题直接崩溃,类似于其他语言中的assert。
Result<T,E>
对应可以挽救的error,Result是一个枚举类型
enum Result<T, E> {Ok(T),Err(E),
}
使用案例:
fn plus_one(x: Option<i32>) -> Option<i32> {match x { //match就类似于C里面的switch语句None => None,Some(i) => Some(i + 1),}
}let five = Some(5);
let six = plus_one(five);
let none = plus_one(None);
当函数正常运行时,返回Ok包裹着的返回结果,当函数运行失败时,返回Err包裹的错误类型,
一般使用Result的工作流程就是:函数返回一个Result,然后使用match匹配结果:
use std::fs::File;
use std::io::ErrorKind;fn main() {let f = File::open("hello.txt");let f = match f {Ok(file) => file,Err(error) => match error.kind() {ErrorKind::NotFound => match File::create("hello.txt") {Ok(fc) => fc,Err(e) => panic!("Problem creating the file: {:?}", e),},other_error => panic!("Problem opening the file: {:?}", other_error),},};
}
Result也可以通过unwrap或者except转换为panic:
use std::fs::File;fn main() {let f = File::open("hello.txt").unwrap();//不出问题就提取出来返回结果,出问题就直接paniclet f = File::open("hello.txt").expect("Failed to open hello.txt");//跟上面一样的效果,不过会报错自定义的错误提示
}
panic
对应不可恢复error,出现panic代码直接崩溃
fn main() {panic!("crash and burn");
}
更多关于panic的请看Rust圣经
相关文章:

Rust编程(三)生命周期与异常处理
生命周期 生命周期,简而言之就是引用的有效作用域。在大多数时候,我们无需手动的声明生命周期,因为编译器可以自动进行推导。生命周期的主要作用是避免悬垂引用,它会导致程序引用了本不该引用的数据: {let r;{let x …...

【办公类-21-11】 20240327三级育婴师 多个二级文件夹的docx合并成docx有页码,转PDF
背景展示:有页码的操作题 背景需求: 实操课终于全部结束了,把考试内容(docx)都写好了 【办公类-21-10】三级育婴师 视频转文字docx(等线小五单倍行距),批量改成“宋体小四、1.5倍行…...

OSG编程指南<二十一>:OSG视图与相机视点更新设置及OSG宽屏变形
1、概述 什么是视图?在《OpenGL 编程指南》中有下面的比喻,从笔者开始学习图形学就影响深刻,相信对读者学习场景管理也会非常有帮助。 产生目标场景视图的变换过程类似于用相机进行拍照,主要有如下的步骤: (1)把照相机固定在三脚架上,让它对准场景(视图变换)。 (2)…...
Laplace变换-3
回忆#常见函数的Laplace变换: t z − 1 ↦ Γ ( z ) s z t^{z-1} \mapsto \frac{\Gamma(z)}{s^{z}} tz−1↦szΓ(z) (要求 R e ( z ) > 0 \mathrm{Re}(z)>0 Re(z)>0) e a t ↦ 1 s − a e^{at} \mapsto \frac{1}{s-a} eat↦s−a1…...

LVS负载均衡-DR模式配置
LVS:Linux virtual server ,即Linux虚拟服务器 LVS自身是一个负载均衡器(Director),不直接处理请求,而是将请求转发至位于它后端的真实服务器real server上。 LVS是四层(传输层 tcp/udp)负载均衡…...

【unity】如何汉化unity Hub
相信大家下载安装unity后看着满操作栏的英文,英文不好的小伙伴们会一头雾水。但是没关系你要记住你要怎么高速运转的机器进入中国,请记住我给出的原理,不懂不代表不会用啊。现在我们就来把编译器给进行汉化。 第一步:我们打开Uni…...

【算法】KMP-快速文本匹配
文章目录 一、KMP算法说明二、详细实现1. next数组定义2. 使用next加速匹配3. next数组如何快速生成4. 时间复杂度O(mn)的证明a) next生成的时间复杂度b) 匹配过程时间复杂度 三、例题1. [leetcode#572](https://leetcode.cn/problems/subtree-of-another-tree/description/)2.…...

多维数组和交错数组笔记
1.) 关于数据的几个概念: Rank,即数组的维数,其值是数组类型的方括号之间逗号个数加上1。 Demo:利用一维数组显示斐波那契数列F(n) F(n-1) F(n-2) (n >2 ),每行显示5项,20项. static void Main(string[] args){int[] F n…...

Python(django)之单一接口展示功能前端开发
1、代码 建立apis_manage.html 代码如下: <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><title>测试平台</title> </head> <body role"document"> <nav c…...
【大模型】非常好用的大语言模型推理框架 bigdl-llm,现改名为 ipex-llm
非常好用的大语言模型推理框架 bigdl-llm,现改名为 ipex-llm bigdl-llmgithub地址环境安装依赖下载测试模型加载和优化预训练模型使用优化后的模型构建一个聊天应用 bigdl-llm IPEX-LLM is a PyTorch library for running LLM on Intel CPU and GPU (e.g., local P…...
Kubernetes示例yaml:3. service-statefulset.yaml
service-statefulset.yaml 示例 apiVersion: apps/v1 kind: statefulset metadata:...... spec:......volumeMounts:- name: pvcmountPath: /var/lib/arangodb3VolumeClaimTemplates:- metadata:name: pvcspec:accessModes: [ "ReadWriteOnce" ]storangeClassName: …...

Windows平台cmake编译QT源码库,使用VScode开发QT
不愿意安装庞大的QT开发IDE,可以编译QT源码库。 下载源码可以用国内镜像,如清华大学的:Index of /qt/archive/qt/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 我用的是 6.5.3,进去之后,不要下载整个源…...
腾讯云轻量8核16G18M服务器多少钱一年?
腾讯云轻量8核16G18M服务器多少钱一年?优惠价格4224元15个月,买一年送3个月。配置为轻量应用服务器、16核32G28M、28M带宽、6000GB月流量、上海/广州/北京、380GB SSD云硬盘。 腾讯云服务器有两个活动,一个是官方的主会场入口,还…...

二分练习题——123
123 二分等差数列求和前缀和数组 题目分析 连续一段的和我们想到了前缀和,但是这里的l和r的范围为1e12,明显不能用O(n)的时间复杂度去求前缀和。那么我们开始观察序列的特点,可以按照等差数列对序列进行分块。如上图,在求前10个…...

淘宝详情数据采集(商品上货,数据分析,属性详情,价格监控),海量数据值得get
淘宝详情数据采集涉及多个环节,包括商品上货、数据分析、属性详情以及价格监控等。在采集这些数据时,尤其是面对海量数据时,需要采取有效的方法和技术来确保数据的准确性和完整性。以下是一些关于淘宝详情数据采集的建议: 请求示…...

Django之Web应用架构模式
一、Web应用架构模式 在开发Web应用中,有两种模式 1.1、前后端不分离 在前后端不分离的应用模式中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控制前端的展示。前端与后端的耦合度很高 1.2、前后端分离 在前后端分离的应用模式中,后端仅返…...

GPT提示词分享 —— 口播脚本
可用于撰写视频、直播、播客、分镜头和其他口语内容的脚本。 提示词👇 请以人的口吻,采用缩略语、成语、过渡短语、感叹词、悬垂修饰语和口语化语言,避免重复短语和不自然的句子结构,撰写一篇关于 [主题] 的文章。 GPT3.5&#…...

笔记本作为其他主机显示屏(HDMI采集器)
前言: 我打算打笔记本作为显示屏来用,连上工控机,这不是贼方便吗 操作: 一、必需品 HDMI采集器一个 可以去绿联买一个,便宜的就行,我的大概就长这样 win10下载 PotPlayer 软件 下载链接:h…...

02.percona Toolkit工具pt-archiver命令实践
1.命令作用 Percona Toolkit有的32个命令,可以分为7大类 工具类别 工具命令 工具作用 备注 开发类 pt-duplicate-key-checker 列出并删除重复的索引和外键 pt-online-schema-change 在线修改表结构 pt-query-advisor 分析查询语句,并给出建议&#x…...
【天狼启航者】研究计划
“造车”,预计在4月中旬展开(嵌入式蓝桥杯比赛结束后),这里先计划一下,不断更新。 基本要求: 使用STM32F407系列芯片,使用FreeRTOS系统。 驱动程序必须要有强大的可移植性、模块化、低耦合、简…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...

免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

6.9-QT模拟计算器
源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...
多元隐函数 偏导公式
我们来推导隐函数 z z ( x , y ) z z(x, y) zz(x,y) 的偏导公式,给定一个隐函数关系: F ( x , y , z ( x , y ) ) 0 F(x, y, z(x, y)) 0 F(x,y,z(x,y))0 🧠 目标: 求 ∂ z ∂ x \frac{\partial z}{\partial x} ∂x∂z、 …...
【题解-洛谷】P10480 可达性统计
题目:P10480 可达性统计 题目描述 给定一张 N N N 个点 M M M 条边的有向无环图,分别统计从每个点出发能够到达的点的数量。 输入格式 第一行两个整数 N , M N,M N,M,接下来 M M M 行每行两个整数 x , y x,y x,y,表示从 …...

VSCode 没有添加Windows右键菜单
关键字:VSCode;Windows右键菜单;注册表。 文章目录 前言一、工程环境二、配置流程1.右键文件打开2.右键文件夹打开3.右键空白处打开文件夹 三、测试总结 前言 安装 VSCode 时没有注意,实际使用的时候发现 VSCode 在 Windows 菜单栏…...