Generics Rust说函数参数没有足够的寿命,即使已经设置了适当的寿命

Generics Rust说函数参数没有足够的寿命,即使已经设置了适当的寿命,generics,rust,closures,lifetime,trait-objects,Generics,Rust,Closures,Lifetime,Trait Objects,对于后台上下文:我正在创建一个基于观察者/订阅者的全局事件系统(使用单个共享事件系统)。我决定使用FnMut作为回调闭包。放置在临时结构数据数据的impl处的生存期'a(&mut self,mut callback:F){ >| self.o.push(&mut回调as&mut dyn FnMut(u32)->()); > | ------------^^^^^^^^^^^^^------------------------------ > | |

对于后台上下文:我正在创建一个基于观察者/订阅者的全局事件系统(使用单个共享事件系统)。我决定使用
FnMut
作为回调闭包。放置在临时结构
数据数据的
impl
处的生存期
'a
(&mut self,mut callback:F){ >| self.o.push(&mut回调as&mut dyn FnMut(u32)->()); > | ------------^^^^^^^^^^^^^------------------------------ > | | | >| |借来的价值不够长久 >|参数要求为“a”借用“callback” > | } >|-`callback`在仍然借来的时候掉在了这里
例如:

使用std::any::any;
使用std::mem;
使用std::rc::rc;
使用std::cell::RefCell;
结构事件()>,
}
恳求{
fn订阅服务器()+'a>(&mut self,mut回调:F){
self.o.push(&mut回调as&mutdynfnmut(u32)->());
}
}
fn main(){
让mute=Event{obs:Vec::new()};
设x=3;
e、 订户(|n |{x+n;});
}
callback
参数使用
F
泛型,它肯定受到生存期
'a
的约束。但是错误仍然出现,表明
回调
参数的寿命不够长

callback
的寿命足够长,但问题是您没有存储收到的
callback
,而是存储了转换为trait对象(
dyn
)的trait对象的数据,并且该trait对象的数据必须归某个对象所有

我最初使用
Box
作为
dyn-FnMut(u32)
的容器,但是
Box
要求回调是
静态的

不,没有。这包括:

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));
    }
}

callback
参数使用
F
泛型,它肯定受到生存期
'a
的约束。但是错误仍然出现,表明
回调
参数的寿命不够长

callback
的寿命足够长,但问题是您没有存储收到的
callback
,而是存储了转换为trait对象(
dyn
)的trait对象的数据,并且该trait对象的数据必须归某个对象所有

我最初使用
Box
作为
dyn-FnMut(u32)
的容器,但是
Box
要求回调是
静态的

不,没有。这包括:

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));
    }
}

我忘了说
要求
回调
静态
,因为我需要将泛型转换为特征对象。无所谓。实际上,我不知道你可以直接将一个泛型框起来,它会自动成为一个trait对象?@galaticExplorer它不会因为你框起来就自动成为trait对象,但是。因此,由于您正在请求一个trait对象(通过存储到
Vec
),rustc知道寻找有效的强制,找到一个,一切都正常。我忘了说
要求
回调
静态
,因为我需要将该泛型转换为trait对象。无需担心。实际上,我不知道你可以直接将一个泛型框起来,它会自动成为一个trait对象?@galaticExplorer它不会因为你框起来就自动成为trait对象,但是。因此,由于您正在请求一个trait对象(通过存储到
Vec
),rustc知道寻找有效的强制,找到一个,一切都正常。