008 Rust死灵书之生命周期
介绍
本系列录制的视频主要放在B站上Rust死灵书学习视频
Rust相关的源码资料在:github.com/anonymousGiga
笔记内容
今天我们跟大家聊一聊生命周期。
命周期说白了就是作用域的名字。每一个引用以及包含引用的数据结构,都要有一个生命周期来指定它保持有效的作用域。
考虑以下一段代码:
fn main() {
{
let mut data: Vec<i32> = vec![1, 2, 3];
{
let x: &i32 = &data[0];
{
//Vec::push(&mut data, 4);
}
println!("{}", x);
}
}
println!("Hello, world!");
}
如果去掉生命周期的语法糖,则等价于如下代码:
fn main() {
//等价于如下:
'a: {
let mut data: Vec<i32> = vec![1, 2, 3];
'b: {
let x: &'b i32 = Index::index::<'b>(&'b data, 0);
'c: {
//Vec::push(&'c mut data, 4);
}
println!("{}", x);
}
}
println!("Hello, world!");
}
我们先描述一下我们这段代码的逻辑:
1、创建一个vector data,并赋初值{1, 2, 3};
2、创建data[0]的引用x;
3、给data中添加一个元素;
4、打印整个data中的元素。
这段代码的逻辑是没有问题的,但是在Rust中无法编译通过,为什么?
Rust可能出于如下的原因拒绝编译这段代码:我们有一个有效的指向 data 的内部数据的引用 x,而同时又创建了一个 data 的可变引用用于执行push。也就是说出现了可变引用的别名,这违背了引用的第二条规则。
但是 Rust 其实并非因为这个原因判断这段代码有问题。Rust 不知道 x 是 data 的子内容的引用,它其实完全不知道 Vec 的内部是什么样子的。它只知道 x 必须在’b 范围内有效,这样才能打印其中的内容。函数 Index::index 的签名因此要求传递的 data 的引用也必须在’b 的范围内有效。当我们调用 push 的时候,Rust 发现我们要创建一个 &’c mut data。它知道’c 是包含在’b 以内的,因为 &’b data 还存活着,所以它拒绝了这段程序。
本作品采用《CC 协议》,转载必须注明作者和本文链接