跳转到主要内容
模块 6 · 第 1 课(共 2)课程中的11/14~15 min
模块课程(1/2)

寿命和参考

在 Rust 中,每个引用都有一个生命周期,它对应于该引用有效的范围。大多数时候,由于生命周期省略规则,生命周期是隐式的并由编译器推断。然而,当不同引用的生命周期之间的关系不明确时,我们必须明确地注释它们。

生命周期的主要目标是防止悬空引用(对已从内存中释放的数据的引用)。


生命周期注释语法

生命周期名称以撇号 (') 开头,通常是短小写字母(如 'a)。生命周期注释不会改变变量的实际生命周期,但它们向编译器指示输入和输出的有效性之间的关系。

例如,如果一个函数接受两个字符串引用参数并返回一个字符串引用,并且我们希望只要两个输入参数都有效,返回的引用就有效,我们使用:

Rust
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

数据结构中的生命周期

如果结构体包含作为引用的字段,我们必须显式注释该引用的生命周期,以确保结构体实例的生命周期不会比它所引用的数据的生命周期长:

Rust
struct ImportantExcerpt<'a> {
    part: &'a str,
}

fn main() {
    let novel = String::from("Call me Ishmael. Some years ago...");
    let first_sentence = novel.split('.').next().unwrap();
    let i = ImportantExcerpt {
        part: first_sentence,
    };
}

静态寿命

'static 生命周期是一个特殊的生命周期,持续整个程序的整个持续时间。所有字符串文字 (&str) 隐式具有 'static 生命周期,因为它们直接存储在二进制可执行文件内。

Rust
let s: &'static str = "I have a static lifetime.";

自己尝试一下

练习 1:最长函数

锻炼#rust.m6.l1.e1
尝试:0加载中...

编写一个名为longest<'a> 的函数,它接受两个参数:&'a str 类型的x 和&'a str 类型的y,并返回&'a str 类型的值。在函数内部,使用 if/else 块,如果长度大于 y,则返回 x,否则返回 y。

正在加载编辑器...
显示提示

使用 `fnlongest<'a>(x: &'a str, y: &'a str) -> &'a str` 声明签名。然后使用“if x.len() > y.len() { x } else { y }”。

3 次尝试后可用的解决方案

练习 2:带引用的结构

锻炼#rust.m6.l1.e2
尝试:0加载中...

定义一个名为 Excerpt<'a> 的结构,其中包含一个名为 &'a str 类型的部分的字段。在 main 函数中,创建一个名为 text 的字符串变量,并通过借用对 text 的引用来实例化 Excerpt 类型的变量 excerpt。打印摘录部分。

正在加载编辑器...
显示提示

使用“struct Excerpt <'a> {part:&'a str }”。在 main 中用 `Excerpt { part: &text }` 实例化它。

3 次尝试后可用的解决方案

练习 3:静态引用

锻炼#rust.m6.l1.e3
尝试:0加载中...

声明一个名为 message 的变量,并为静态生命周期 (&'static str) 使用显式类型注释,并为其分配一个字符串文字。打印消息的值。

正在加载编辑器...
显示提示

使用语法 `let message: &'static str = 'Messaggio statico!';` 显式注释静态生命周期。

3 次尝试后可用的解决方案