首页 > 解决方案 > 如何理解 Rust 中函数参数和返回值的生命周期?

问题描述

我是 Rust 的新手,我仍然在 Rust 中挣扎。Rust 编程语言书将生命周期定义为

该引用有效的范围

当上下文是单个函数时,很容易理解。例如,在下面的代码中,s 的生命周期是蓝色框,x 的生命周期是绿色框等。

在此处输入图像描述

说到函数,我不太明白函数参数和返回值的生命周期到底意味着什么。假设我们有这个功能:

fn parse_record<'i>(input: &'i [u8]) -> Record<'i> { ... }

签名声明input参数和返回值Record必须具有相同的生命周期'i。这是否意味着当我们调用函数时,我们传递给函数的值和返回的值必须具有相同的生命周期?例如,我可以main像这样调用函数中的函数:

fn main() {
    let mut v: Vec<u8> = [1_u8, 2_u8, 3_u8].to_vec();
    let result = parse_record(&v);
    // use v and result ...
}

函数签名中的生命周期是否表明vresultinmain必须具有相同的生命周期?

标签: rustlifetime

解决方案


我想在这里澄清一下,引用Rust by Example

生命周期是编译器(或更具体地说,它的借用检查器)用来确保所有借用有效的构造。具体来说,变量的生命周期从创建时开始,到销毁时结束。虽然生命周期和作用域经常一起被提及,但它们并不相同。

举个例子,我们通过 & 借用一个变量。借用的生命周期取决于它的声明位置。因此,只要在贷方被销毁之前结束,借入就有效。但是,借用的范围取决于使用引用的位置。

似乎 Rust 书造成了很多混乱,但当我们谈论拥有数据(而不是借用它)生命周期和范围匹配的简单绑定时,确实是不同的东西scopelifetime

如果我们有这样的简单代码。的生命周期a并将b与它们定义的范围相匹配。

fn main() {
    let a = 1;
    let b = 2;
}

在此示例中,贷方 ( a) 比借用更早地超出范围。

fn main() {

    let b;
    {
        let a = 1;
        b = &a;
    }
    let c = *b;
}

它强制编译器发出错误。


error[E0597]: `a` does not live long enough
 --> src/main.rs:5:9
  |
5 |         b = &a;
  |         ^^^^^^ borrowed value does not live long enough
6 |     }
  |     - `a` dropped here while still borrowed
7 |     let c = *b;
  |             -- borrow later used here

所以 hereb的生命周期比 的生命周期长a,因为它的作用域更大。请记住,借用范围取决于引用的使用位置。

但是这段代码编译得很好,因为范围在被删除b后并没有结束。a

fn main() {
    let b;
    {
        let a = 1;
        b = &a;
        let c = *b;
    }
}

要澄清的另一件事是引用&'lifetime手段的生命周期语法。这意味着引用应该与'lifetime生命周期一样长。不应该是那样的一生。

假设Record元素是这样定义的。

struct Record<'a> {
   some_member: &'a Type
}

此签名仅意味着某些记录成员应与传递给的引用一样长,input反之亦然。

fn parse_record<'i>(input: &'i [u8]) -> Record<'i> { ... }

如果我把它翻译成简单的英语。只要内部的字段Record没有超出范围,传递给函数的引用的贷方就不应超出范围(丢弃)。

或者函数的返回值应该与函数的输入参数一样长。

如果我们没有受输入生命周期约束的返回值,则翻译会发生变化。

fn test<'a>(a: &'a i32, b: &'a i32)

这意味着在函数执行结束之前,贷方a和贷方b应该在范围内。

在许多简单的情况下,编译器会忽略生命周期,您不必担心它们。实际上,在您的示例中,也可以省略生命周期。

fn parse_record(input: &[u8]) -> Record { ...  }

我建议您阅读Rust by Example有关生命的章节以更实际地理解它们。


推荐阅读