我正在学习rust,我被一个关于Rc、Weak和RefCell的问题卡住了。这个用例是实现一个功能完备的树,其中每个节点都有一个父节点和一系列子节点。文档提供了一个很好的起点:
use std::cell::RefCell;
use std::rc::{Rc, Weak};
#[derive(Debug)]
struct Node {
value: i32,
parent: RefCell<Weak<Node>>,
children: RefCell<Vec<Rc<Node>>>,
}
fn main() {
let leaf = Rc::new(Node {
value: 3,
parent: RefCell::new(Weak::new()),
children: RefCell::new(vec![]),
});
println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
let branch = Rc::new(Node {
value: 5,
parent: RefCell::new(Weak::new()),
children: RefCell::new(vec![Rc::clone(&leaf)]),
});
*leaf.parent.borrow_mut() = Rc::downgrade(&branch);
println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
}
但是,当我试图扩展这个节点时,设计出现了问题。我无法向已经包含的节点添加新节点。branch
节点有一个子节点,但我认为这是唯一可能的,因为我们在创建branch
之前就已经知道leaf
将是唯一的子节点。如果不是这样,在Rc
中创建了branch
之后,我们能否以某种方式更改它,并将leaf
添加为子对象?
或者我应该离开这个设计,采用看起来更像这样的设计:
#[derive(Debug)]
struct Node {
value: i32,
parent: Weak<RefCell<Node>>,
children: Vec<Rc<RefCell<Node>>>,
}
1条答案
按热度按时间pu82cl6c1#
您可以使用下列程式码加入新的Leaf:
话虽如此,你的替代建议
Node
类型似乎是大多数rustaceans会去/更熟悉。