Rust 入门 生命周期
生命周期
- Rust 中的每一个引用都有其 生命周期(lifetime)
- 生命周期就是引用保持有效的作用域
- 大多数情况下: 声明周期是隐式的, 可推断的
- 当引用的声明周期可能以不同的方式互相关联时, 需要我们手动标注生命周期
声明周期避免了悬垂引用
-
生命周期的主要作用就是为了避免悬垂引用
-
示例: 尝试使用离开作用域的值的引用
借用检查器
- Rust 编译器有一个 借用检查器(borrow checker)
- 它比较作用域来确保所有的借用都是有效的
- 示例: 尝试使用离开作用域的值的引用 (生命周期标注)
- 示例: 修改上述代码使其编译通过
函数中的泛型生命周期
- 示例: 比较字符串长度
- 示例: 修改上述代码使其编译通过
生命周期标注
- 生命周期标注不会改变引用的生命周期长度
- 当指定了泛型生命周期参数后, 函数可以接受带有任何生命周期的的引用
- 生命周期标注: 描述多个引用的生命周期相互的关系, 不会影响其引用的生命周期
生命周期参数名称
- 以
'
开头 (撇号 也叫单引号) - 通常使用全小写的命名
- 非常短, 通常使用一个字母表示
生命周期标注的位置
- 在引用符号(
&
)之后 - 使用空格将标注和类型分开
示例
&i32
一个引用&'a i32
带有显示标注生命周期的引用&'a mut i32
带有显示标注生命周期的可变引用
函数签名中的生命周期标注
- 在函数签名中必须先定义泛型生命周期参数
- 示例:
深入理解生命周期
- 指定生命周期参数的方式依赖于函数所做的事情
- 示例:
- 从函数中返回引用时, 返回类型的生命周期参数必须与参数中的生命周期相匹配
结构体中的生命周期标注
- 结构体中的字段可以是自持有的类型
- 结构体中的字段也可以是引用类型
- 若结构体中的字段是引用类型
- 需要手动添加声明周期标注
- 例子:
生命周期的省略
- 在 Rust 语言的早期版本中, 每个函数都必须显示的标注生命周期
- 后来 Rust 的开发团队发现有些情况下生命周期是可以被推断的
于是 Rust 开发团队将一些可以推断声明周期的情况写入借用检查器中 - 例子: 早期 Rust 的函数生命周期标注(pre-1.0)
- 例子: 现在 Rust 的函数声明周期标注中的省略
- 需要注意的是: 不是所有的生命周期标注都可以省略
声明周期的省略规则
- 被编码进 Rust 引用分析的模式被称为 生命周期省略规则(lifetime elision rules)
- 这些规则不需要开发者来遵守
- 这是一些特殊情况, 需要由编译器来考虑
- 如果你的代码符合这些情况, 就不需要显示的标注生命周期
- 声明周期省略规则不会提供完整的推断
- 如果应用规则后, 引用的声明周期仍然模糊不清, 就会导致编译错误
- 解决办法就是手动添加声明周期标注
- 输入/输出声明周期:
- 函数或方法的参数的生命周期被称为 输入生命周期(input lifetimes)
- 返回值的生命周期被称为 输出生命周期(output lifetimes)
- 声明周期省略规则:
- 每个引用类型的参数都有自己的声明周期
- 如果只有一个输入声明周期参数, 那么该生命周期会被赋予所有的输出声明周期参数
- 如果输入生命周期参数中包含
&self
或者&mut self
, 那么self
的声明周期会被赋给所有的输出声明周期参数
- 编译器使用上述三条规则在没有显式标注声明周期的情况下,来确定引动的声明周期
- 第一条规则用于输入生命周期
- 后两条规则用于输出声明周期
- 如果编译器使用了这三个规则之后仍然无法确定声明周期的引用, 就会编译失败
- 这三条适用于
fn
定义和impl
中
方法定义中的生命周期标注
-
在结构体上使用生命周期实现方法, 语法和泛型相同
-
在哪声明和使用生命周期参数, 依赖于:
- 生命周期参数是否和字段, 方法的参数或返回值有关
-
结构体字段的生命周期名:
- 在
impl
后声明 - 在结构体名称后使用
- 这些生命周期是结构体类型的一部分
- 在
-
实现块内的方法签名中:
- 引用必须绑定结构体字段的声明周期, 或者引用独立
- 生命周期省略规则经常使得方法中的生命周期标注不是必须的
-
例子:
静态声明周期
'static
是一个特殊的声明周期- 它表示整个程序的运行时间
- 例如:
- 所有的字符串字面值就是
'static
- 所有的字符串字面值就是
- 在为引用指定
'static
之前一定要三思
例子:
- 在这个例子中使用了:
- 泛型参数类型
- Trait Bound
- 声明周期
如果对我分享的内容感兴趣的话 记得关注我得动态
求推荐 求收藏 求转发 求关注
求推荐 求收藏 求转发 求关注
__EOF__

本文作者:Delayer
本文链接:https://www.cnblogs.com/delayer/articles/14986086.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/delayer/articles/14986086.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!