与“Vec”中的自引用结构的生命周期不匹配

Lifetime mismatch with self referencing structs in a `Vec`

我有以下代码,您也可以在 playground 中看到:

struct Node<'a> {
    parent: Option<&'a Node<'a>>,
    name: &'a str,
}

fn looper(nodes: &mut Vec<Node>) {
    for i in 0..nodes.len() {
        let n = &nodes[i];
        let next_node = Node {
            parent: Some(n),
            name: "please compile",
        };
        nodes.push(next_node);
    }
}

它应该采用 VecNode 并附加 Node 到它引用已经在 Vec 中的 Node。不幸的是我得到这个错误:

error[E0623]: lifetime mismatch
  --> src/main.rs:13:20
   |
6  | fn looper(nodes: &mut Vec<Node>) {
   |                  -------------- these two types are declared with different lifetimes...
...
13 |         nodes.push(next_node);
   |                    ^^^^^^^^^ ...but data from `nodes` flows into `nodes` here

如何编译?解释如何在这种情况下考虑生命周期会很有用。我知道这可能是一个问题,因为 variance 但我不确定如何改写我的问题以提供我想要的功能。

一般规则:当某些值的类型或它实现的特征具有生命周期参数时,该生命周期总是比值本身的生命周期 — 该值具有保证它包含的引用在被删除之前不会失效。

事实上,在您的示例中我们可以看到,如果不是这种情况,则生命周期检查将是不健全的;您正在 nodes 添加 值,但没有什么可以阻止 looper 中删除 nodes,这将使引用这些值的任何 parent 引用无效。

构建树或链表引用的唯一实用方法(没有特殊用途的不安全代码,它有特定的计划来保持事物的完整性)是编写一个递归的功能;每个函数调用框架都可以引用由其调用者(及其调用者的调用者等)构造的节点。借用检查器接受了这一点,因为每个帧都有自己新的、更短的引用生命周期(引用总是可以被视为具有比开始时更短的生命周期)。