Rust Vec到切片会话的显式生存期
我希望对列表中的更改进行回调,因此我创建了一个简单的示例:Rust Vec到切片会话的显式生存期,rust,Rust,我希望对列表中的更改进行回调,因此我创建了一个简单的示例: struct Foo; struct FooList { list: Vec<Foo>, on_change_cb: Vec<Box<FnMut(& mut [Foo])>>, } impl FooList { /* pub fn register_on_change_cb2<F>(&mut self, cb: F) where F: FnMu
struct Foo;
struct FooList {
list: Vec<Foo>,
on_change_cb: Vec<Box<FnMut(& mut [Foo])>>,
}
impl FooList {
/*
pub fn register_on_change_cb2<F>(&mut self, cb: F) where F: FnMut(&mut [Foo]) {
self.on_change_cb.push(Box::new(cb));
}*/
pub fn register_on_change_cb(&mut self, cb: Box<FnMut(&mut [Foo])>) {
self.on_change_cb.push(cb);
}
pub fn push(&mut self, foo: Foo) {
self.list.push(foo);
self.on_change();
}
fn on_change(&mut self) {
for cb in &mut self.on_change_cb {
cb(&mut self.list);
}
}
}
structfoo;
结构傻瓜{
名单:Vec,,
关于变更,cb:Vec,
}
傻瓜{
/*
发布fn寄存器\u on\u change\u cb2(&mut self,cb:F),其中F:FnMut(&mut[Foo]){
自动更改cb推送(Box::new(cb));
}*/
发布fn寄存器打开更改cb(&mut self,cb:Box){
自换式cb推送(cb);
}
pub fn push(&mut self,foo:foo){
self.list.push(foo);
self.on_change();
}
fn on_更改(&mut self){
对于cb in和mut self.on_change_cb{
cb(和多个自身列表);
}
}
}
Vec
,那么编译器在这里使用什么生命周期呢?如果我这样更改代码:
struct FooList<'a> {
list: Vec<Foo>,
on_change_cb: Vec<Box<FnMut(&'a mut [Foo])>>,
}
impl<'a> FooList<'a> {
struct-woulist>,
}
恳求{
我得到一个编译时错误:
错误[E0495]:无法推断借用的适当生存期
由于相互冲突的要求而导致的表达
&mut[Foo]
的生命周期小于但不等于整个傻瓜对象的生命周期
F
可能寿命不够长
如何在不要求回调的静态
生存期的情况下修复此错误?我只想调用Box::new
我将试着回答你的问题1和3,因为问题2要么是多余的,要么是与其他问题正交的,我不知道你真正想通过它实现什么。也许它应该有一个自己的问题
傻瓜列表
对象,都有一个生存期'a
,因此傻瓜列表
中的每个回调都只包含至少生存了'a
的引用。”这种解释可能会使编写register\u on\u change\u cb2
的原型更容易:它接受一个回调,该回调也只包含至少存在'a
的引用
impl<'a> FooList<'a> {
pub fn register_on_change_cb2<F>(&mut self, cb: F)
where F: FnMut(&mut [Foo]) + 'a
{
self.on_change_cb.push(Box::new(cb));
}
在本例中,您不能插入捕获短命的
的闭包,因为它不超过(推断的)生存期'a
。但您可以插入捕获长寿命的
的闭包,因为编译器可以推断满足这两个约束的生存期'a
:
必须比'a
更长寿,因为列表
属于列表
愚人类型我将尝试回答你的问题1和3,因为问题2要么是多余的,要么是与其他问题正交的,我无法告诉你真正想要通过它实现什么。也许它值得一个自己的问题
- 如果您有一个引用的函数,但它不需要任何有关引用的生存期信息,那么它必须能够接受anylife的引用。下面是它的显式语法(这是编译器从您编写的代码中推断的): 这类似于:“对于每个
对象,都有一个生存期傻瓜列表
,因此'a
中的每个回调都只包含至少生存了傻瓜列表
的引用。”这种解释可能会使编写'a
的原型更容易:它接受一个回调,该回调也只包含至少存在register\u on\u change\u cb2
的引用'a
在本例中,您不能插入捕获impl<'a> FooList<'a> { pub fn register_on_change_cb2<F>(&mut self, cb: F) where F: FnMut(&mut [Foo]) + 'a { self.on_change_cb.push(Box::new(cb)); }
的闭包,因为它不超过(推断的)生存期短命的
。但您可以插入捕获'a
的闭包,因为编译器可以推断满足这两个约束的生存期长寿命的
:'a
必须比'a
更长寿,因为列表
属于列表
傻瓜类型,请只拥有一个。@Shepmaster实际上,我认为这些问题是同一事物的不同方面,如何
+slice+Vec
合作,这就是为什么我把这些问题合并成一个问题,请只拥有一个。@Shepmaster Actuallly,我认为这些问题是同一事物的不同方面,如何FnMut
+slice+Vec
合作,这就是为什么我把这些问题组合成一个汉克,但为什么生命在FnMut
中很重要?我把3
放进cb
框中,然后我通过值得到它?@user1244932
Boxe关于它包含的引用的知识。我添加了一个示例,说明
生命周期如何确保'a
只包含比cb
傻瓜
生命周期长的引用。谢谢,但是为什么在
中生命周期很重要?我将3
放入cb
框中,然后通过值得到它?@user1244932
>我添加了一个例子,说明框
生存期如何确保'a
只包含比cb
寿命长的引用。傻瓜
impl<'a> FooList<'a> { pub fn register_on_change_cb2<F>(&mut self, cb: F) where F: FnMut(&mut [Foo]) + 'a { self.on_change_cb.push(Box::new(cb)); }
let longlived = String::from("hello"); let mut list = FooList { list: Vec::new(), on_change_cb: Vec::new(), }; list.register_on_change_cb2(|_| println!("{}", longlived)); // ok let shortlived = String::from("hello"); list.register_on_change_cb2(|_| println!("{}", shortlived)); // `shortlived` does not live long enough list.push(Foo);
pub fn register_on_change_cb2<F>(&mut self, cb: F) where F: FnMut(&mut [Foo]) + 'static
- 如果您有一个引用的函数,但它不需要任何有关引用的生存期信息,那么它必须能够接受anylife的引用。下面是它的显式语法(这是编译器从您编写的代码中推断的): 这类似于:“对于每个