强制一个结构比另一个结构长寿
Force a struct to outlive another struct
我有两个结构。第一个“父”结构包含一个需要显式清理的资源,我通过派生 Drop
特性来处理它。第二个“子”结构是从父结构中检索的,需要所述资源尚未被释放才能有效。
换句话说,任何父实例都必须比它的子实例长。
我的解决方案使用引用来使借用检查器强制执行此规则。
struct Parent {
// Private resource data.
}
impl Parent {
fn new() -> Self {
Parent {}
}
fn new_child(&self) -> Child {
return Child { _parent: self };
}
}
impl Drop for Parent {
fn drop(&mut self) {
// Do some cleanup after which no instance of Child will be valid.
}
}
struct Child<'a> {
_parent: &'a Parent,
// Private data.
}
impl<'a> Child<'a> {
fn hello(&self) {
println!("Hello Child!");
}
}
fn main() {
let parent = Parent::new();
let child = parent.new_child();
child.hello();
// Fails to compile with the following line uncommented (as intented).
// drop(parent);
// child.hello();
}
这可行,但 Child
实际上不需要知道其父级。我想用 PhantomData
:
替换参考字段
struct Child<'a> {
_parent: PhantomData<&'a Parent>,
// Private data.
}
但在这种情况下,我如何才能在 Parent::new_child
中“绑定”_parent
到父实例?
您可以执行以下操作:
struct Parent {
// Private resource data.
}
struct Child<'a> {
_parent: PhantomData<&'a Parent>,
// Private data.
}
impl Parent {
// The returned child borrows from self
fn new_child(&self) -> Child<'_> {
Child { _parent: PhantomData }
}
}
这应该会给你想要的行为。
我有两个结构。第一个“父”结构包含一个需要显式清理的资源,我通过派生 Drop
特性来处理它。第二个“子”结构是从父结构中检索的,需要所述资源尚未被释放才能有效。
换句话说,任何父实例都必须比它的子实例长。
我的解决方案使用引用来使借用检查器强制执行此规则。
struct Parent {
// Private resource data.
}
impl Parent {
fn new() -> Self {
Parent {}
}
fn new_child(&self) -> Child {
return Child { _parent: self };
}
}
impl Drop for Parent {
fn drop(&mut self) {
// Do some cleanup after which no instance of Child will be valid.
}
}
struct Child<'a> {
_parent: &'a Parent,
// Private data.
}
impl<'a> Child<'a> {
fn hello(&self) {
println!("Hello Child!");
}
}
fn main() {
let parent = Parent::new();
let child = parent.new_child();
child.hello();
// Fails to compile with the following line uncommented (as intented).
// drop(parent);
// child.hello();
}
这可行,但 Child
实际上不需要知道其父级。我想用 PhantomData
:
struct Child<'a> {
_parent: PhantomData<&'a Parent>,
// Private data.
}
但在这种情况下,我如何才能在 Parent::new_child
中“绑定”_parent
到父实例?
您可以执行以下操作:
struct Parent {
// Private resource data.
}
struct Child<'a> {
_parent: PhantomData<&'a Parent>,
// Private data.
}
impl Parent {
// The returned child borrows from self
fn new_child(&self) -> Child<'_> {
Child { _parent: PhantomData }
}
}
这应该会给你想要的行为。