rust - 无法借用对捕获树中结构的引用,因为它的生命周期不够长

标签 rust lifetime borrow-checker

我有一个带有节点和子节点的树结构,以及来自 GUI 库的循环,该循环期望在每次迭代时运行一个函数。我正在努力让借用检查器让我保留对正在处理的节点的引用 - 它提示 nodes 的生命周期不够长。

这是一个最小的复制品:

#[derive(Debug)]
struct Node {
    value: u64,
    children: Vec<Node>,
}

fn run_loop<F>(mut handler: F)
where
    F: 'static + FnMut(),
{
    for _ in 0..500 {
        handler();
    }
}

fn main() {
    let nodes = vec![
        Node {
            value: 1,
            children: vec![Node {
                value: 3,
                children: vec![],
            }],
        },
        Node {
            value: 2,
            children: vec![],
        },
    ];
    let mut node = &nodes[0];

    run_loop(move || {
        println!("Node: {:?}", node);
        node = &node.children[0];
    });
}
error[E0597]: `nodes` does not live long enough
  --> src/main.rs:30:21
   |
30 |       let mut node = &nodes[0];
   |                       ^^^^^ borrowed value does not live long enough
31 | 
32 | /     run_loop(move || {
33 | |         println!("Node: {:?}", node);
34 | |         node = &node.children[0];
35 | |     });
   | |______- argument requires that `nodes` is borrowed for `'static`
36 |   }
   |   - `nodes` dropped here while still borrowed

Rust Playground

完成这项工作的最佳方法是什么?我无法更改 run_loop 的结构。理想情况下,我不会更改 Node 的结构(它是从第三方库返回的对象,因此虽然我可以将该对象解析为新的数据结构,但这并不优雅)。我可以通过在 main 中进行更改来让借用检查员感到满意吗?

最佳答案

it complains that nodes doesn't live long enough.

那是因为事实并非如此。 run_loop 函数要求其参数永远存在('static)。 nodes 变量不会永远存在,因此捕获它的闭包也不会永远存在。

简单的解决方法是将 run_loop 更改为不需要永久存在的参数(通过删除 'static 约束),但如果您不能这样做,那么您可以让节点永远存在。您可以通过“泄露”它来做到这一点。

let nodes = vec![ /*...*/ ];
let nodes = Vec::leak(nodes);
let mut node = &nodes[0];

(Playground link)

目前,这需要 nightly,但稳定版本的 Box 中也有类似的泄漏功能。

let nodes = vec![ /*...*/ ];
let nodes = Box::leak(nodes.into_boxed_slice());
let mut node = &nodes[0];

(Playground link)

关于rust - 无法借用对捕获树中结构的引用,因为它的生命周期不够长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63192441/

相关文章:

rust - 为什么在变量上调用方法会阻止 Rust 推断变量的类型?

pointers - 为什么在对取消引用的枚举进行匹配时必须使用 ref?

rust - 如何分配给匹配分支内的匹配表达式中使用的变量?

struct - 如何在结构中存储clap::ArgMatches?

reference - 如何使用 `AsRef` 参数?

rust - 无法在结构中包含 ImageBuffer — 需要两个参数并且只提供了一个

rust - 代数数据类型的特征

iterator - 如何编写返回对自身的引用的迭代器?

rust - 在本地存储对象后无法确定处理引用的生命周期

rust - Rust 中的多重可变引用预防是如何工作的?