2015-09-20 74 views
2

我希望能够在Parent中存储名为Child的结构,其中Child包含引用返回给父代。尝试将自引用数据拆分为单独的结构

它的工作原理,如果我直接有Child结构像这样的家长里:

struct Parent<'s> { 
    cache: RefCell<Vec<Child<'s>>> 
} 

但是,如果我移动Vec到一个单独的结构,那么它会失败,一生的错误进行编译。

struct Parent<'s> { 
    cache: RefCell<Cache<'s>> 
} 

struct Cache<'s> { 
    children: Vec<Child<'s>> 
} 

可以让这个例子与单独的结构一起工作吗?

这是full working code,编译好。当将children移动到单独的结构中时,它就是fails

我对这个问题的分析:

Parent包含children直接,'s是相同的寿命为Parent结构本身的范围,因此,我可以调用采取&'s selfParent方法。

Parent包含Cache含有children's是相同的寿命作为Cache结构,这是Parent之前创建的范围内,因而这是不可能呼吁Parent称取&'s self方法。尝试这样做将产生误差

<anon>:33:15: 33:16 error: `p` does not live long enough 
<anon>:33  let obj = p.create_object(); 
         ^
<anon>:30:48: 38:2 note: reference must be valid for the block suffix following statement 0 at 30:47... 
<anon>:30  let cache = Cache { children: Vec::new() }; // the lifetime `'s` is essentially from this line to the end of the program 
<anon>:31  let mut p = Parent { cache: RefCell::new(cache) }; // although the Parent instance was created here, 's still refers to the lifetime before it 
<anon>:32  // this fails because p doesn't live long enough 
<anon>:33  let obj = p.create_object(); 

我需要缩短'sParent范围,而不是Cache范围的一种方式。

免责声明: 这个问题是非常相似的,我问较早(https://stackoverflow.com/questions/32579518/rust-lifetime-error-with-self-referencing-struct?noredirect=1#comment53014063_32579518)中标记为重复。我已经阅读了答案,我相信我超越了这一点,因为我可以获得引用的正确时间(如我的第一个示例中所示)。我再次问这个(现在稍微不同)的问题,因为我现在有一个有效的具体例子,一个不起作用。我确信用一个结构可以完成两个,对吧?

回答

2

您可以通过强制CacheParent将它们定义在相同的let绑定中来使其具有相同的生命周期来进行编译。

fn main() { 
    let (cache, mut p); 
    cache = Cache { children: Vec::new() }; 
    p = Parent { cache: RefCell::new(cache) }; 
    let obj = p.create_object(); 

    let c1 = Child { parent: &p, data: 1 }; 
    p.cache.borrow_mut().children.push(c1); 
} 

在这里,我们本质上是声明一个解构的元组,然后初始化它。我们不能在let结合直接初始化元组:

let (cache, mut p) = (Cache { children: Vec::new() }, Parent { cache: RefCell::new(cache) }); 

因为初始化为p引用cache,但这个名字直到let语句的末尾定义。独立的初始化工作,因为编译器跟踪哪些变量被初始化;如果您交换了分配的顺序,你会得到一个编译器错误:

<anon>:31:38: 31:43 error: use of possibly uninitialized variable: `cache` [E0381] 
<anon>:31  p = Parent { cache: RefCell::new(cache) }; 
相关问题