【发布时间】:2021-03-25 07:45:11
【问题描述】:
我从已排序节点的Vec 开始,然后使用此排序将这些节点链接到二叉树中,然后返回基本结构
// Test name
#[derive(Clone)]
struct Struct {
parent: Option<Rc<RefCell<Struct>>>,
superscript: Option<Rc<RefCell<Struct>>>,
subscript: Option<Rc<RefCell<Struct>>>,
height: u32,
center: u32,
symbols: VecDeque<u8>
}
最终得到由上述Structs 形成的二叉树。在这一点上,这些Structs 是唯一拥有的,所以我想我可以从使用Rc<RefCell<Struct>> 转换为RefCell<Struct>(认为Box<Struct> 由于内部可变性而不起作用?),但我不确定这如何或是否有助于解决我遇到的问题。
在此之后,我需要以一种新颖的方式遍历Structs,并在整个递归过程中通过调用.pop_front()改变属于各种Structs 的各种symbols。
我当前的实现会导致thread 'main' panicked at 'already borrowed: BorrowMutError' 的各种实例。
它的功能(请原谅复杂的逻辑):
fn traverse_scripts(row: Rc<RefCell<Struct>>) {
if let Some(superscript_row) = &row.borrow().superscript {
if let Some(superscript_symbol) = superscript_row.borrow().symbols.front() {
if let Some(current_row_symbol) = row.borrow().symbols.front() {
if superscript_symbol < current_row_symbol {
println!("^{{{}",*superscript_symbol);
superscript_row.borrow_mut().symbols.pop_front();
traverse_scripts(Rc::clone(superscript_row));
}
}
else {
println!("^{{{}",*superscript_symbol);
superscript_row.borrow_mut().symbols.pop_front();
traverse_scripts(Rc::clone(superscript_row));
}
}
}
if let Some(subscript_row) = &row.borrow().subscript {
if let Some(subscript_symbol) = subscript_row.borrow().symbols.front() {
if let Some(current_row_symbol) = row.borrow().symbols.front() {
if subscript_symbol < current_row_symbol {
print!("_{{{}",*subscript_symbol);
subscript_row.borrow_mut().symbols.pop_front();
traverse_scripts(Rc::clone(subscript_row));
}
}
else {
print!("_{{{}",*subscript_symbol);
subscript_row.borrow_mut().symbols.pop_front();
traverse_scripts(Rc::clone(subscript_row));
}
}
}
if let Some(current_row_symbol) = row.borrow().symbols.front() {
if let Some(parent_row) = &row.borrow().parent {
if let Some(parent_symbol) = parent_row.borrow().symbols.front() {
if current_row_symbol < parent_symbol {
print!(" {}",*current_row_symbol);
row.borrow_mut().symbols.pop_front();
traverse_scripts(Rc::clone(&row));
}
}
}
else {
print!(" {}",*current_row_symbol);
row.borrow_mut().symbols.pop_front();
traverse_scripts(Rc::clone(&row));
}
}
if let Some(parent_row) = &row.borrow().parent {
if let Some(parent_symbol) = parent_row.borrow().symbols.front() {
print!("}} {}",*parent_symbol);
row.borrow_mut().symbols.pop_front();
traverse_scripts(Rc::clone(parent_row));
} else {
print!("}}");
traverse_scripts(Rc::clone(parent_row));
}
}
}
我考虑过使用Arc<Mutex<Struct>> 来代替遍历,但鉴于它不是多线程的,我认为没有必要?
我想我可能在这里遗漏了一个相对简单的想法,我非常感谢任何帮助。
如果我在我的问题中遗漏了任何内容,请发表评论,我会尝试添加。
【问题讨论】:
-
此时,这些
Structs是唯一拥有的:可以创建具有唯一所有权的树,但不是这样:每个节点可能由其子中的父链接,以及其父中的子链接。如果你想切换到Box,你必须删除父链接。 -
Mutex也无济于事,顺便说一句-lock方法的工作方式与RefCell上的borrow_mut相同。所以你最终会遇到同样的问题。
标签: memory-management rust borrowing