了解Rust中参数化结构的生命周期

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了了解Rust中参数化结构的生命周期相关的知识,希望对你有一定的参考价值。

以下代码

struct Cat<'a, T> {
    coolness: &'a T,
}

抱怨说

error[E0309]: the parameter type `T` may not live long enough
 --> src/main.rs:2:5
  |
1 | struct Cat<'a, T> {
  |                - help: consider adding an explicit lifetime bound `T: 'a`...
2 |     coolness: &'a T,
  |     ^^^^^^^^^^^^^^^
  |
note: ...so that the reference type `&'a T` does not outlive the data it points at
 --> src/main.rs:2:5
  |
2 |     coolness: &'a T,
  |     ^^^^^^^^^^^^^^^

使用明确的生命周期绑定,它会编译。当我实例化T&i32的结构时,尽管每个引用具有不同的生命周期,但代码编译。我的理解是编译器看到内部&比外部&更长:

struct Cat<'a, T>
where
    T: 'a,
{
    coolness: &'a T,
}

fn main() {
    let b = 10;
    {
        let c = &b;
        {
            let fluffy = Cat { coolness: &c };
        }
    }
}

Cat { coolness: &c }扩展到Cat { coolness: &'a &'a i32 }吗?对于更多嵌套引用,内部引用是否也具有相同的生命周期等等?

答案

Cat { coolness: &c }扩展到Cat { coolness: &'a &'a i32 }吗?

是的,Cat最终会引用参考文献。这可以通过以下代码编译来演示:

let fluffy = Cat { coolness: &c };
fn is_it_a_double_ref(_x: &Cat<&i32>) {}
is_it_a_double_ref(&fluffy);

但是,每个参考的寿命不一定相同。

我的理解是,编译器看到内部&超出外部&

那就对了。这恰恰是T: 'a开始发挥作用的地方。

一开始就有点理解生命时间的界限。他们对T中包含的引用加以限制。例如,给定绑定的T: 'static,不包含任何引用的类型,或仅包含'static引用,例如i32&'static str,满足边界,而包含非'static引用的类型,例如&'a i32,不要,因为'a: 'static是假的。更一般地,给定绑定的T: 'aT类型满足约束,如果对于'x上的每个生命周期参数T'x: 'a为真(没有生命周期参数的类型通常满足边界)。

现在回到你的代码。让我们给这些参考文献命名。我们会说coolness的类型是&'fluffy &'c i32'c是变量c的生命周期,而'fluffy是变量fluffy的生命周期(违反直觉,生命周期编码借用的范围,而不是指示物的生命周期,尽管编译器确实检查借用不会超出指示物的范围一生)。这意味着Fluffy的类型是Cat<'fluffy, &'c i32>&'c i32: 'fluffy是真的吗?

要检查&'c i32: 'fluffy是否为真,我们需要检查'c: 'fluffy是否为真。 'c: 'fluffy是真的,因为变量cfluffy之后超出了范围。

以上是关于了解Rust中参数化结构的生命周期的主要内容,如果未能解决你的问题,请参考以下文章

在 Rust 中使用带有结构的生命周期的正确方法是啥?

什么是非词汇生命周期?

了解生命周期:最大生命周期和“静态”

Rust学习笔记1.基础语法

Rust学习笔记1.基础语法

Rust 中的闭包生命周期通过简单的模式