我需要两个物体;一个对象是拥有第二个对象的容器。
struct OuterObject {
foo: InnerObject,
}
impl OuterObject {
/// Creates a new instance of OuterObject
fn new() -> OuterObject {
OuterObject {
foo: InnerObject::new(false),
}
}
/// Returns a mutable reference to the InnerObject
fn get_foo(&mut self) -> &mut InnerObject {
self.foo
}
}
struct InnerObject {
baz: bool,
}
impl InnerObject {
/// Creates a new instance of InnerObject
fn new(baz: bool) -> InnerObject {
InnerObject {
baz: baz,
}
}
}
到目前为止一切顺利。但我的InnerObject
需要一种方法来引用拥有它的OuterObject
。这意味着我应该将对OuterObject
的引用传递给InnerObject
的构造函数。但这意味着OuterObject
的构造函数无法编译,因为self
无法在构造函数中引用:
struct OuterObject {
foo: InnerObject,
vorg: u8,
}
impl OuterObject {
/// Creates a new instance of OuterObject
fn new() -> OuterObject {
OuterObject {
foo: InnerObject::new(&self, false), // fails; 'self' cannot be referenced in constructor
vorg: 1,
}
}
/// Returns a mutable reference to the InnerObject
fn get_foo(&mut self) -> &mut InnerObject {
self.foo
}
/// Returns OuterObject's vorg value
fn get_vorg(&self) -> u8 {
self.vorg
}
}
struct InnerObject {
blah: &OuterObject
baz: bool,
}
impl InnerObject {
fn new(blah: &OuterObject, baz: bool) -> InnerObject {
InnerObject {
blah: blah,
baz: baz,
}
}
/// Calculates something based on the state of the OuterObject that owns this InnerObject
fn calculate_something(&self) -> u8 {
self.blah.get_vorg() + 2
}
}
下一个计划:由于我无法在构造函数中引用self
,我尝试使用延迟加载:
struct OuterObject {
foo: Option<InnerObject>,
vorg: u8,
}
impl OuterObject {
/// Creates a new instance of OuterObject
fn new() -> OuterObject {
OuterObject {
foo: None,
vorg: 1,
}
}
/// Returns a mutable reference to the InnerObject
fn get_foo(&mut self) -> &mut InnerObject {
// lazy-loads the object
if self.foo.is_none() {
self.foo = Some(InnerObject::new(&self, false));
}
self.foo.as_mut().unwrap() // should always be safe
}
/// Returns OuterObject's vorg
fn get_vorg(&self) -> u8 {
self.vorg
}
}
struct InnerObject {
blah: &OuterObject
baz: bool,
}
impl InnerObject {
fn new(blah: &OuterObject, baz: bool) -> InnerObject {
InnerObject {
blah: blah,
baz: baz,
}
}
/// Calculates something based on the state of the OuterObject that owns this InnerObject
fn calculate_something(&self) -> u8 {
self.blah.get_vorg() + 2
}
}
现在编译器关注生命周期。我很难找到如何在Option
内指示对象生命周期的文档。例如,如果我用这种方式编写它,InnerObject
需要成为特征的编译器:
Option<InnerObject + 'a>
1)OuterObject
和InnerObject
之间的理想关系注定要失败吗?
2)如果没有,我应该使用不同的设计模式吗?
3)如果我追求的设计模式是可行的,我该如何使其发挥作用?