0

我正在编写一个简短的程序来随机生成一个视频游戏地牢,但是我在干净地创建树中的子地牢时遇到了一些麻烦。

我所拥有的是丑陋的,并且意味着运行时检查借用RefCell,即使树在创建后不需要可变性。

由于它是一棵树,我使用Rc<T>andWeak<T>来分别保存对子节点和父节点的引用。这产生了一个问题,因为子节点的值取决于其父节点的值,因此需要创建父节点以便为其子节点提供父节点引用,而需要创建子节点以向父节点提供其子字段。

如果我使用在父节点之前创建子节点的函数(例如,通过在父节点实例化之前将父字段的相关值传递给它们),它们当然将无法获得对其父节点的引用。

我可以让它工作的唯一方法RefCell是在创建每个节点后使用它们设置子节点,如图所示。

这是每个节点的结构:

pub struct Dungeon {
    x: u32,
    y: u32,
    end_x: u32,
    end_y: u32,
    parent: Option<Weak<RefCell<Dungeon>>>,
    left: Option<Rc<RefCell<Dungeon>>>,
    right: Option<Rc<RefCell<Dungeon>>>,
}

这是给定根地牢的用于生成树的函数的概述:

fn subdungeons(
    parent: Rc<RefCell<SubDungeon>>,
    level: u32,
) -> (Option<Rc<RefCell<Dungeon>>>, Option<Rc<RefCell<Dungeon>>>) {
    // These two lines are a stand-in for the actual code used to generate
    // the values for a child dungeon given its parent. The 'left'
    // and 'right' fields are necessarily 'None' after creation
    let mut left_sub: Dungeon = Dungeon::generate(Rc::downgrade(&parent));
    let mut right_sub: Dungeon = Dungeon::generate(Rc::downgrade(&parent));

    if level != 0 {
        let (l, r) = subdungeons(Rc::clone(&left_sub), level - 1);
        left_sub.borrow_mut().left = l;
        left_sub.borrow_mut().right = r;

        let (l, r) = subdungeons(Rc::clone(&right_sub), level - 1);
        right_sub.borrow_mut().left = l;
        right_sub.borrow_mut().right = r;
    }

    (Some(left_sub), Some(right_sub))
}

有没有办法以不涉及引入的方式重写它RefCell?树在创建后不需要是可变的,但我想不出任何其他方法来打破父级需要创建子级才能被实例化的循环,但子级也需要父级已经被实例化创建以获取其父引用。

当然,这在普通树中不会成为问题,其中推送到父节点的节点的值通常与父节点的值无关,但我似乎无法找到一个好的 Rust 解决方案来解决像这样的情况.

4

0 回答 0