脚本之家

电脑版
提示:原网页已由神马搜索转码, 内容由www.jb51.net提供.
您的位置:首页软件编程Rust语言→ Rust生命周期

深入了解Rust的生命周期

  更新时间:2022年12月14日 10:50:52  作者:闲鱼翻不了身 
生命周期指的是引用保持有效的作用域,Rust的每个引用都有自己的生命周期。本文将通过示例和大家详细说说Rust的生命周期,需要的可以参考一下

Rust生命周期简介

Rust 中的每一个引用都有其 生命周期(lifetime),也就是引用保持有效的作用域。

生命周期的主要目标是避免悬垂引用,它会导致程序引用了非预期引用的数据。

{
let r;
{
let x = 5;
r = &x;
}
//x出作用域后已经被删除,发生悬垂引用
println!("r: {}", r);
}

实现生命周期检查的手段:Rust 编译器有一个 借用检查器(borrow checker),它比较作用域来确保所有的借用都是有效的。

//函数中的泛型生命周期
fn longest(x: &str, y: &str) -> &str {
if x.len() > y.len() {
x
} else {
y
}
}
//该函数会发生编译错误,因为 Rust 并不知道将要返回的引用是指向 x 或 y
//当我们定义这个函数的时候,并不知道传递给函数的具体值,所以也不知道到底是 if 还是 else 会被执行。
//我们也不知道传入的引用的具体生命周期,所以也就不能通过观察作用域来确定返回的引用是否总是有效。
//借用检查器自身同样也无法确定,因为它不知道 x 和 y 的生命周期是如何与返回值的生命周期相关联的。

生命周期标注语法:

生命周期语法是用于将函数的多个参数与其返回值的生命周期进行关联的。一旦他们形成了某种关联,Rust 就有了足够的信息来允许内存安全的操作并阻止会产生悬垂指针亦或是违反内存安全的行为。

Q:为什么有这个语法?

A:因为编译器笨,借用检查器不知道类似上述情况中的生命周期怎么比较,所以靠人手写给他约束。

生命周期标注并不改变任何引用的生命周期的长短。与当函数签名中指定了泛型类型参数后就可以接受任何类型一样,当指定了泛型生命周期后函数也能接受任何生命周期的引用。生命周期标注描述了多个引用生命周期相互的关系,而不影响其生命周期。

生命周期标注有着一个不太常见的语法:生命周期参数名称必须以撇号(')开头,其名称通常全是小写,类似于泛型其名称非常短。'a是大多数人默认使用的名称。生命周期参数标注位于引用的 &之后,并有一个空格来将引用类型与生命周期标注分隔开。

//使用泛型生命周期标注语法解决上述问题
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
//现在函数签名表明对于某些生命周期 'a,函数会获取两个参数,他们都是与生命周期 'a 存在的一样长的字符串 slice。
//函数会返回一个同样也与生命周期 'a 存在的一样长的字符串 slice。
//它的实际含义是 longest 函数返回的引用的生命周期与传入该函数的引用的生命周期的较小者一致。
//这就是我们告诉 Rust 需要其保证的约束条件。
//两个直观的例子
//1.正确示例:返回的引用生命周期与较小的string2一致,函数调用正确
fn main() {
let string1 = String::from("long string is long");
{
let string2 = String::from("xyz");
let result = longest(string1.as_str(), string2.as_str());
println!("The longest string is {}", result);
}
}
//2.错误示例:返回的引用生命周期与string2一致,但是println时,result引用生命周期已经结束,编译失败
fn main() {
let string1 = String::from("long string is long");
let result;
{
let string2 = String::from("xyz");
result = longest(string1.as_str(), string2.as_str());
}
println!("The longest string is {}", result);
}

类似的,结构体,方法中使用到引用时也可以使用生命周期标注语法。

题外话:Rust观法有在尽力的减轻开发者负担,一些很常见的需要生命周期标注的情况,编译器已经在内部实现好了,未来用户只会越来越少的使用到生命周期标注语法。被Rust 官方考虑到的一些引用分析的模式被称为 生命周期省略规则(lifetime elision rules)。

比较特殊的,'static,其生命周期能够存活于整个程序期间。所有的字符串字面量都拥有 'static生命周期。

//static生命周期
let s: &'static str = "I have a static lifetime.";

总结:

生命周期概念和大多数语言一样,但Rust对变量生命周期的检查是很具有特色的,还有他特别的生命周期标注语法是很性新颖的,能在编译期处理的错误绝不留到运行时这是Rust很棒的设计理念.

到此这篇关于深入了解Rust的生命周期的文章就介绍到这了,更多相关Rust生命周期内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

    • 哈希表也是集合中的一种,也是最常用的集合形式,目前Rust语言核心部分没有对哈希表进行实现,是使用标准库提供的,这篇文章主要介绍了Rust语言之哈希表,需要的朋友可以参考下
      2024-02-02
    • 声明式宏使得你能够写出类似 match 表达式的东西,来操作你所提供的 Rust代码,它使用你提供的代码来生成用于替换宏调用的代码,感兴趣的可以了解一下
      2023-12-12
    • 自定义的数据类型,为相关联的值命名,打包成有意义的组合,类似python的dict,但是赋值的时候可以不按顺序,本文给大家介绍下rust中的struct知识,感兴趣的朋友一起看看吧
      2022-10-10
    • 这篇文章主要介绍了Rust 智能指针的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
      2024-01-01
    • 这篇文章主要介绍了Rust应用调用C语言动态库,本文记录了笔者编写一个简单的C语言动态库,并通过Rust调用动态库导出的函数,需要的朋友可以参考下
      2023-01-01
    • 本文主要介绍了Rust常用特型之Drop特型,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
      2024-03-03
    • Prometheus 是一个开源的系统监控和警报工具包,最初是由SoundCloud构建的,随着时间的发展,Prometheus已经具有适用于各种使用场景的版本,为了开发者方便开发,更是有各种语言版本的Prometheus的开发工具包,本文主要介绍Rust版本的Prometheus开发工具包
      2023-10-10
    • 这篇文章主要为大家详细介绍了如何利用rust编一个静态博客工具,这个静态博客的工具主要是把md文档转为html静态网站/博客,感兴趣的小伙伴可以跟随小编一起学习一下
      2023-12-12
    • trait用中文来讲就是特征,它就是一个标记,只不过这个标记被用在特定的地方,也就是类型参数的后面,下面我们就来学习一下trait的具体使用方法吧
      2023-12-12
    • 这篇文章主要为大家介绍了Rust语言从入门到精通系列之Iterator迭代器深入详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
      2023-04-04

    最新评论