Rust 说函数参数的寿命不够,即使已经放置了适当的寿命
Rust says the function parameter does not live enough, even though proper lifetime have been placed
对于背景上下文:我正在创建一个基于 Observer/Subscriber 的全局事件系统(使用单个共享事件系统)。我决定使用 FnMut
作为我的回调闭包。放置在临时结构 Data<'a>
的 impl
处的生命周期 'a
应该允许方法 mut_func()
中的 callback
参数与整个 Data
结构。因为 callback
参数使用 F
泛型,它肯定受到生命周期 'a
的约束。但是错误仍然出现,指出 callback
参数的寿命不够长。
我最初使用 Box<T>
作为 dyn FnMut(u32)
的容器,但是 Box<T>
要求回调为 'static
(因为我将盒装泛型转换为一个框特征对象)在我的场景中是无法实现的(为了可读性)。然后我尝试使用 Rc<RefCell<T>>
,遗憾的是它不支持特征对象。
此外,我对 callback
参数使用泛型,因为我希望该函数具有更高的可读性,而不是必须看到 Box<T>
环绕整个闭包 将 无处不在,因为这个事件系统将是我程序的核心部分。我会尽一切努力使 'front-end' 更具可读性和更清晰(除了显着的性能影响)。
注意:这是我的示例程序。如果需要,我可以 post 实际程序。
错误:
error[E0597]: `callback` does not live long enough
> | impl<'a> Data<'a> {
> | -- lifetime `'a` defined here
> | fn mut_func<F: FnMut(u32) -> () + 'a>(&mut self, mut callback: F) {
> | self.o.push(&mut callback as &mut dyn FnMut(u32) -> ());
> | ------------^^^^^^^^^^^^^------------------------------
> | | |
> | | borrowed value does not live long enough
> | argument requires that `callback` is borrowed for `'a`
> | }
> | - `callback` dropped here while still borrowed
示例:
use std::any::Any;
use std::mem;
use std::rc::Rc;
use std::cell::RefCell;
struct Event<'a> {
obs: Vec<&'a mut dyn FnMut(u32) -> ()>,
}
impl<'a> Event<'a> {
fn subscriber<F: FnMut(u32) -> () + 'a>(&mut self, mut callback: F) {
self.o.push(&mut callback as &mut dyn FnMut(u32) -> ());
}
}
fn main () {
let mut e = Event {obs: Vec::new()};
let x = 3;
e.subscriber(|n| {x+n;});
}
the callback
parameter uses the F
generic which is definitely constrained by the lifetime 'a
. But the error is still appearing stating that the callback
parameter does not live long enough.
callback
寿命足够长,但问题是您没有存储收到的 callback
,而是存储它 转换为特征对象 (dyn
) 并且该特征对象的数据必须归某物所有。
I originally used Box<T>
as my container for the dyn FnMut(u32)
, but the Box<T>
requires the callback to be 'static
不,不是。这编译:
struct Event<'a> {
obs: Vec<Box<dyn FnMut(u32) -> () + 'a>>,
}
impl<'a> Event<'a> {
fn subscriber<F: FnMut(u32) -> () + 'a>(&mut self, callback: F) {
self.obs.push(Box::new(callback));
}
}
然后再进行一项更改,您的示例将编译:在 e
之前定义 x
以便 x
比 e
寿命更长:
fn main() {
let x = 3;
let mut e = Event {obs: Vec::new()};
e.subscriber(|n| {x+n;});
}
对于背景上下文:我正在创建一个基于 Observer/Subscriber 的全局事件系统(使用单个共享事件系统)。我决定使用 FnMut
作为我的回调闭包。放置在临时结构 Data<'a>
的 impl
处的生命周期 'a
应该允许方法 mut_func()
中的 callback
参数与整个 Data
结构。因为 callback
参数使用 F
泛型,它肯定受到生命周期 'a
的约束。但是错误仍然出现,指出 callback
参数的寿命不够长。
我最初使用 Box<T>
作为 dyn FnMut(u32)
的容器,但是 Box<T>
要求回调为 'static
(因为我将盒装泛型转换为一个框特征对象)在我的场景中是无法实现的(为了可读性)。然后我尝试使用 Rc<RefCell<T>>
,遗憾的是它不支持特征对象。
此外,我对 callback
参数使用泛型,因为我希望该函数具有更高的可读性,而不是必须看到 Box<T>
环绕整个闭包 将 无处不在,因为这个事件系统将是我程序的核心部分。我会尽一切努力使 'front-end' 更具可读性和更清晰(除了显着的性能影响)。
注意:这是我的示例程序。如果需要,我可以 post 实际程序。
错误:
error[E0597]: `callback` does not live long enough
> | impl<'a> Data<'a> {
> | -- lifetime `'a` defined here
> | fn mut_func<F: FnMut(u32) -> () + 'a>(&mut self, mut callback: F) {
> | self.o.push(&mut callback as &mut dyn FnMut(u32) -> ());
> | ------------^^^^^^^^^^^^^------------------------------
> | | |
> | | borrowed value does not live long enough
> | argument requires that `callback` is borrowed for `'a`
> | }
> | - `callback` dropped here while still borrowed
示例:
use std::any::Any;
use std::mem;
use std::rc::Rc;
use std::cell::RefCell;
struct Event<'a> {
obs: Vec<&'a mut dyn FnMut(u32) -> ()>,
}
impl<'a> Event<'a> {
fn subscriber<F: FnMut(u32) -> () + 'a>(&mut self, mut callback: F) {
self.o.push(&mut callback as &mut dyn FnMut(u32) -> ());
}
}
fn main () {
let mut e = Event {obs: Vec::new()};
let x = 3;
e.subscriber(|n| {x+n;});
}
the
callback
parameter uses theF
generic which is definitely constrained by the lifetime'a
. But the error is still appearing stating that thecallback
parameter does not live long enough.
callback
寿命足够长,但问题是您没有存储收到的 callback
,而是存储它 转换为特征对象 (dyn
) 并且该特征对象的数据必须归某物所有。
I originally used
Box<T>
as my container for thedyn FnMut(u32)
, but theBox<T>
requires the callback to be'static
不,不是。这编译:
struct Event<'a> {
obs: Vec<Box<dyn FnMut(u32) -> () + 'a>>,
}
impl<'a> Event<'a> {
fn subscriber<F: FnMut(u32) -> () + 'a>(&mut self, callback: F) {
self.obs.push(Box::new(callback));
}
}
然后再进行一项更改,您的示例将编译:在 e
之前定义 x
以便 x
比 e
寿命更长:
fn main() {
let x = 3;
let mut e = Event {obs: Vec::new()};
e.subscriber(|n| {x+n;});
}