文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

深入了解Rust的生命周期

2022-12-14 12:01

关注

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生命周期内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯