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,并赋初值{123}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 协议》,转载必须注明作者和本文链接
令狐一冲
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!