一段代码:
use std::mem::*;
trait Child {
fn do_something(&mut self, value: u32);
}
trait Parent<'a> {
type Remove;
// add a child to the parent, RAII-like pattern
// we assume that child may change its internal state when parent does its calls on child's methods, but the child doesn't have to
fn put(&'a mut self, child: &'a mut dyn Child) -> Self::Remove;
// just a helper method
fn put_callback(&'a mut self, callback: &'a dyn Fn(u32) -> ()) -> CallbackRemove<'a, Self::Remove> {
let mut remove = CallbackRemove {
child: CallbackChild { callback },
remove: MaybeUninit::uninit()
};
remove.remove = MaybeUninit::new(self.put(&mut remove.child));
remove
}
}
struct CallbackChild<'a> {
callback: &'a dyn Fn(u32) -> ()
}
impl<'a> Child for CallbackChild<'a> {
fn do_something(&mut self, value: u32) -> () {
(self.callback)(value)
}
}
struct CallbackRemove<'a, R> {
child: CallbackChild<'a>,
remove: MaybeUninit<R>
}
Foo1
、Foo2
、Bar1
、foo2_to_foo1
可以是任何有意义的东西,它们的内容对问题没有任何影响。
有 2 个错误:
bar2
bar2.foo1
的生命周期不够长,因为&mut bar2.foo1
的生命周期是'_
,而foo1
中func1
的生命周期需要'a
,尽管我明确声明了bar2
的生命周期问题是我们通过
bar2
借用了 bar2
,即使用已经初始化的 bar2
的字段来初始化 bar2
的字段。看起来借用应该在那行之后结束,因为我们将值借回给所有者。
而且,
&mut bar2.foo1
确实活得足够长,因为我们返回值,并且指定了返回值的生命周期,即&mut bar2.foo1
应该有'a
生命周期。
我只需要如何摆脱这些错误,这些错误是无意义的(借回的值被视为借用,而不是拥有;具有明确定义生命周期的借用值
'a
实际上存在于'_
)。我想摆脱MaybeUninit
。最简单的方法是在 foo1
范围之外声明 Bar2<'a>
字段,但它不会被返回,并且它的生命周期实际上将是 '_
而不是 'a
。
您对构造的生命周期如何工作感到困惑。考虑一下:
use std::mem::*;
trait Child {
fn do_something(&mut self, value: u32);
}
trait Parent<'a> {
type Remove;
// add a child to the parent, RAII-like pattern
// we assume that child may change its internal state when parent does its calls on child's methods, but the child doesn't have to
fn put<'c>(&'a mut self, child: &'c mut dyn Child) -> Self::Remove;
// just a helper method
fn put_callback(&'a mut self, callback: &'a dyn Fn(u32) -> ()) -> CallbackRemove<'a, Self::Remove> {
let mut remove = CallbackRemove {
child: CallbackChild { callback },
remove: MaybeUninit::uninit()
};
remove.remove = MaybeUninit::new(self.put(&mut remove.child));
remove
}
}
struct CallbackChild<'cb> {
callback: &'cb dyn Fn(u32) -> ()
}
impl Child for CallbackChild<'_> {
fn do_something(&mut self, value: u32) -> () {
(self.callback)(value)
}
}
struct CallbackRemove<'cb, R> {
child: CallbackChild<'cb>,
remove: MaybeUninit<R>
}
传递给 put 的子进程不必活到
'a
为止... put 可以在子进程还活着的时候对子进程做它需要做的事情,并返回完全拥有的移除——即之后孩子可以清理,家长可以对内容为所欲为。
P.S.:我认为你真的应该重新考虑设计,这感觉很麻烦,而且你的意图似乎很复杂。