带有生命周期的 Rust 函数签名

RustRustBeginner
立即练习

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

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

简介

在本实验中,我们将学习 Rust 中带有生命周期的函数签名,其中任何引用都必须带有注释生命周期,并且返回的任何引用都必须与输入具有相同的生命周期,或者是 static。需要注意的是,如果返回没有输入的引用会导致返回对无效数据的引用,则是被禁止的。提供的示例展示了带有生命周期的函数的有效形式,包括带有一个输入引用的函数、带有可变引用的函数、带有多个具有不同生命周期的元素的函数,以及返回作为参数传入的引用的函数。

注意:如果实验未指定文件名,你可以使用任何你想要的文件名。例如,你可以使用 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(("Rust")) -.-> rust/DataStructuresandEnumsGroup(["Data Structures and Enums"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/BasicConceptsGroup -.-> rust/mutable_variables("Mutable Variables") rust/DataTypesGroup -.-> rust/integer_types("Integer Types") rust/DataTypesGroup -.-> rust/string_type("String Type") rust/DataTypesGroup -.-> rust/type_casting("Type Conversion and Casting") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("Method Syntax") subgraph Lab Skills rust/variable_declarations -.-> lab-99205{{"带有生命周期的 Rust 函数签名"}} rust/mutable_variables -.-> lab-99205{{"带有生命周期的 Rust 函数签名"}} rust/integer_types -.-> lab-99205{{"带有生命周期的 Rust 函数签名"}} rust/string_type -.-> lab-99205{{"带有生命周期的 Rust 函数签名"}} rust/type_casting -.-> lab-99205{{"带有生命周期的 Rust 函数签名"}} rust/function_syntax -.-> lab-99205{{"带有生命周期的 Rust 函数签名"}} rust/expressions_statements -.-> lab-99205{{"带有生命周期的 Rust 函数签名"}} rust/method_syntax -.-> lab-99205{{"带有生命周期的 Rust 函数签名"}} end

函数

忽略[省略规则],带有生命周期的函数签名有一些限制:

  • 任何引用必须带有注释生命周期。
  • 任何返回的引用必须与输入具有相同的生命周期,或者是 static

此外,请注意,如果返回没有输入的引用会导致返回对无效数据的引用,则是被禁止的。以下示例展示了一些带有生命周期的函数的有效形式:

// 带有生命周期 `'a` 的一个输入引用,其生命周期必须至少与函数一样长。
fn print_one<'a>(x: &'a i32) {
    println!("`print_one`: x is {}", x);
}

// 带有生命周期的可变引用也是可能的。
fn add_one<'a>(x: &'a mut i32) {
    *x += 1;
}

// 具有不同生命周期的多个元素。在这种情况下,两者具有相同的生命周期 `'a` 是可以的,但在更复杂的情况下,可能需要不同的生命周期。
fn print_multi<'a, 'b>(x: &'a i32, y: &'b i32) {
    println!("`print_multi`: x is {}, y is {}", x, y);
}

// 返回传入的引用是可以接受的。但是,必须返回正确的生命周期。
fn pass_x<'a, 'b>(x: &'a i32, _: &'b i32) -> &'a i32 { x }

//fn invalid_output<'a>() -> &'a String { &String::from("foo") }
// 上面的代码是无效的:`'a` 必须比函数的生命周期长。在这里,`&String::from("foo")` 会创建一个 `String`,然后是一个引用。然后在退出作用域时数据会被丢弃,留下一个对无效数据的引用以供返回。

fn main() {
    let x = 7;
    let y = 9;

    print_one(&x);
    print_multi(&x, &y);

    let z = pass_x(&x, &y);
    print_one(z);

    let mut t = 3;
    add_one(&mut t);
    print_one(&t);
}

总结

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