Rust 生命周期标注与借用检查器

RustRustBeginner
立即练习

This tutorial is from open-source community. Access the source code

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本实验中,将介绍 Rust 中显式生命周期标注的概念,借用检查器会使用这些标注来确定引用的有效性。

注意:如果实验未指定文件名,你可以使用任何你想要的文件名。例如,你可以使用 main.rs,并通过 rustc main.rs &&./main 进行编译和运行。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/DataTypesGroup -.-> rust/integer_types("Integer Types") rust/DataTypesGroup -.-> rust/type_casting("Type Conversion and Casting") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") subgraph Lab Skills rust/variable_declarations -.-> lab-99203{{"Rust 生命周期标注与借用检查器"}} rust/integer_types -.-> lab-99203{{"Rust 生命周期标注与借用检查器"}} rust/type_casting -.-> lab-99203{{"Rust 生命周期标注与借用检查器"}} rust/function_syntax -.-> lab-99203{{"Rust 生命周期标注与借用检查器"}} rust/expressions_statements -.-> lab-99203{{"Rust 生命周期标注与借用检查器"}} end

显式标注

借用检查器使用显式生命周期标注来确定引用的有效时长。在生命周期无法省略的情况下,Rust 需要显式标注来确定引用的生命周期。显式标注生命周期的语法使用一个撇号字符,如下所示:

foo<'a>
// `foo` 有一个生命周期参数 `'a`

与闭包类似,使用生命周期需要泛型。此外,这种生命周期语法表明 foo 的生命周期不能超过 'a 的生命周期。类型的显式标注形式为 &'a T,其中 'a 已经被引入。

在有多个生命周期的情况下,语法类似:

foo<'a, 'b>
// `foo` 有生命周期参数 `'a` 和 `'b`

在这种情况下,foo 的生命周期不能超过 'a'b 的生命周期。

以下是显式生命周期标注的使用示例:

// `print_refs` 接受两个对 `i32` 的引用,它们具有不同的
// 生命周期 `'a` 和 `'b`。这两个生命周期都必须至少与
// 函数 `print_refs` 一样长。
fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) {
    println!("x is {} and y is {}", x, y);
}

// 一个不接受参数但有生命周期参数 `'a` 的函数。
fn failed_borrow<'a>() {
    let _x = 12;

    // 错误:`_x` 的生命周期不够长
    let y: &'a i32 = &_x;
    // 尝试在函数内部将生命周期 `'a` 用作显式类型标注
    // 将会失败,因为 `&_x` 的生命周期比 `y` 的生命周期短。
    // 短生命周期不能被强制转换为长生命周期。
}

fn main() {
    // 创建下面要借用的变量。
    let (four, nine) = (4, 9);

    // 两个变量的借用 (`&`) 被传递给函数。
    print_refs(&four, &nine);
    // 任何被借用的输入必须比借用者的生命周期长。
    // 换句话说,`four` 和 `nine` 的生命周期必须
    // 比 `print_refs` 的生命周期长。

    failed_borrow();
    // `failed_borrow` 不包含强制 `'a` 比函数生命周期长的引用,
    // 但 `'a` 更长。因为生命周期从未受到约束,所以它默认为 `'static`。
}

总结

恭喜你!你已经完成了“显式标注”实验。你可以在 LabEx 中练习更多实验来提升你的技能。