【发布时间】:2020-09-30 04:05:15
【问题描述】:
对于背景上下文:我正在创建一个基于观察者/订阅者的全局事件系统(使用单个共享事件系统)。我决定使用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> 包裹着整个将无处不在的闭包,因为这事件系统将是我计划的核心部分。我会尽一切努力使“前端”更具可读性和更清晰(除了显着的性能影响)。
注意:这是我的示例程序。如果需要,我可以发布实际程序。
错误:
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;});
}
【问题讨论】:
标签: generics rust closures lifetime trait-objects