Rust的生命周期是怎样的
这篇文章主要介绍“Rust的生命周期是怎样的”,在日常操作中,相信很多人在Rust的生命周期是怎样的问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Rust的生命周期是怎样的”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
Rust 生命周期机制是与所有权机制同等重要的资源管理机制。 之所以引入这个概念主要是应对复杂类型系统中资源管理的问题。 引用是对待复杂类型时必不可少的机制,毕竟复杂类型的数据不能被处理器轻易地复制和计算。 但引用往往导致极其复杂的资源管理问题,首先认识一下垂悬引用:
实例
{ let r; { let x = 5; r = &x; } println!("r: {}", r);}
这段代码是不会通过 Rust 编译器的,原因是 r 所引用的值已经在使用之前被释放。
上图中的绿色范围 ‘a 表示 r 的生命周期,蓝色范围 ‘b 表示 x 的生命周期。很显然,’b 比 ‘a 小得多,引用必须在值的生命周期以内才有效。
一直以来我们都在结构体中使用 String 而不用 &str,我们用一个案例解释原因:
实例
fn longer(s1: &str, s2: &str) -> &str { if s2.len() > s1.len() { s2 } else { s1 }}
longer 函数取 s1 和 s2 两个字符串切片中较长的一个返回其引用值。但只这段代码不会通过编译,原因是返回值引用可能会返回过期的引用:
实例
fn main() { let r; { let s1 = "rust"; let s2 = "ecmascript"; r = longer(s1, s2); } println!("{} is longer", r);}
这段程序中虽然经过了比较,但 r 被使用的时候源值 s1 和 s2 都已经失效了。当然我们可以把 r 的使用移到 s1 和 s2 的生命周期范围以内防止这种错误的发生,但对于函数来说,它并不能知道自己以外的地方是什么情况,它为了保障自己传递出去的值是正常的,必选所有权原则消除一切危险,所以 longer 函数并不能通过编译。
生命周期注释
生命周期注释是描述引用生命周期的办法。 虽然这样并不能够改变引用的生命周期,但可以在合适的地方声明两个引用的生命周期一致。 生命收起注释用单引号开头,跟着一个小写字母单词:
&i32 // 常规引用&'a i32 // 含有生命周期注释的引用&'a mut i32 // 可变型含有生命周期注释的引用
让我们用生命周期注释改造 longer 函数:
实例
fn longer'a>(s1: &'a str, s2: &'a str) -> &'a str { if s2.len() > s1.len() { s2 } else { s1 }}
我们需要用泛型声明来规范生命周期的名称,随后函数返回值的生命周期将与两个参数的生命周期一致,所以在调用时可以这样写:
实例
fn main() { let r; { let s1 = "rust"; let s2 = "ecmascript"; r = longer(s1, s2); println!("{} is longer", r); }}
以上两段程序结合的运行结果:
ecmascript is longer
注意:别忘记了自动类型判断的原则。
结构体中使用字符串切片引用
这是之前留下的疑问,在此解答:
实例
fn main() { struct Str'a> { content: &'a str } let s = Str { content: "string_slice" }; println!("s.content = {}", s.content);}
运行结果:
s.content = string_slice
如果对结构体 Str 有方法定义:
实例
impl'a> Stra> { fn get_content(&self) -> &str { self.content }}
这里返回值并没有生命周期注释,但是加上也无妨。这是一个历史问题,早期 Rust 不支持生命周期自动判断,所有的生命周期必须严格声明,但主流稳定版本的 Rust 已经支持了这个功能。
静态生命周期
生命周期注释有一个特别的:’static 。所有用双引号包括的字符串常量所代表的精确数据类型都是 &’static str ,’static 所表示的生命周期从程序运行开始到程序运行结束。
泛型、特性与生命周期协同作战
实例
use std::fmt::Display;fn longest_with_an_announcement'a, T>(x: &'a str, y: &'a str, ann: T) -> &'a str where T: Display{ println!("Announcement! {}", ann); if x.len() > y.len() { x } else { y }}
到此,关于“Rust的生命周期是怎样的”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341