首页 > 解决方案 > 存储在 Struct 中的引用没有足够长的时间来关闭

问题描述

我在另一个结构中持有对结构的引用,这两个结构都在同一个块中声明。后来我想在一个重复运行且永不返回的闭包中使用外部结构。Struct 中的引用显然不够长,但在我的理解中,它不应该超出范围,或者至少应该至少与它所指的 Struct 一样长:

struct MyStruct;

struct ReferenceStruct<'a> {
    reference: &'a MyStruct
}

impl<'a> ReferenceStruct<'a> {
    fn do_something(&self) -> () {}
}

fn run<F>(mut function: F) -> !
where
    F: FnMut() -> () + 'static
{
    loop {
        function();
    }
}

fn main() {
    let my_struct = MyStruct;
    let reference = ReferenceStruct { reference: &my_struct };

    run(move || {
        reference.do_something();
    });
}

游乐场链接

run函数(用于上下文)反映了一个事件循环,类似于 Winit 的,实际上,我有另一个 Struct 拥有被引用的值,但这个例子用更少的行重现它。

错误:

error[E0597]: `my_struct` does not live long enough
  --> src\main.rs:26:50
   |
26 |       let reference = ReferenceStruct { reference: &my_struct };
   |                                                    ^^^^^^^^^^ borrowed value does not live long enough
27 | 
28 | /     run(move ||
29 | |     {
30 | |         reference.do_something();
31 | |     });
   | |______- argument requires that `my_struct` is borrowed for `'static`
32 |   }
   |   - `my_struct` dropped here while still borrowed

似乎my_struct在main的末尾被删除了,但即使程序流以某种方式逃脱了循环,它肯定会持续与引用结构一样长,只要它需要。我不明白这个错误是在哪里或如何发生,或者如何处理它。

标签: structrustreferenceclosureslifetime

解决方案


您的问题是'static传递给run(). 这意味着生命周期reference也是'static因为它被移动到闭包中,这反过来意味着它my_struct也必须具有静态生命周期——但事实并非如此。

幸运的是,你不需要'static这里的界限。如果删除它,一切正常:

...
fn run<F>(mut function: F) -> !
where
    F: FnMut() -> ()
...

但是,如果事件循环需要闭包,这可能不是您的用例中的解决方案'static


推荐阅读