我有两个相互依赖的结构体,在C++中我会用指针来做这个,我正在尝试在Rust中怎么做,到目前为止我试过用Box和Rc,我想既然Rc是一个引用计数器,它应该能处理这个,但是它给了我一个错误。
下面是一个简单的代码示例:
struct A {
b : Rc<B>
}
struct B {
a : Option<Rc<A>>
}
fn main() {
let mut b = B {
a : None
};
let a = A {
b: Rc::new(b)
};
b.a = Some(Rc::new(a));
}
下面是我从中得到的错误:
20 | let mut b = B {
| ----- move occurs because `b` has type `B`, which does not implement the `Copy` trait
...
25 | b: Rc::new(b)
| - value moved here
...
28 | b.a = Some(Rc::new(a));
| ^^^ value partially assigned here after move
在Rust中建立这种关系的正确方法是什么?
2条答案
按热度按时间unftdfkk1#
你不应该对一个对象使用两次
Rc::new
。正确的方法是使用一次Rc::new
,然后根据需要克隆它。更重要的是,为了将b
变异到Rc
之后,你应该将它与RefCell
组合。但是即使你这样做了,你仍然会制造内存泄漏,这很糟糕,一个更好的方法是使用
Weak
和Rc::new_cyclic
来制造循环。这避免了使用单元和内存泄漏。
bwleehnv2#
这是编译(这是单线程示例)
你用Rc来拥有多重所有权,这样你就可以把b移到a,然后仍然把它命名为b,甚至尝试改变它。
Rc是只读的,所以使用RefCell可以隐藏更改内容的事实。
在Rust book https://doc.rust-lang.org/book/ch15-06-reference-cycles.html中还有另一个循环的例子