Rust学习问题树示例,更新Rc内的元素

aiqt4smr  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(155)

我正在学习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>>>,
}
pu82cl6c

pu82cl6c1#

您可以使用下列程式码加入新的Leaf:

let new_leaf = Rc::new(Node {
    value: 4,
    parent: RefCell::new(Rc::downgrade(&branch)),
    children: RefCell::new(vec![])
});

branch.children.borrow_mut().push(new_leaf);

话虽如此,你的替代建议Node类型似乎是大多数rustaceans会去/更熟悉。

相关问题