我试图在二叉树中实现add
操作:
use std::cell::RefCell;
use std::cmp::PartialOrd;
type Link<T> = RefCell<Option<Box<Node<T>>>>;
struct Node<T> {
key: T,
left: Link<T>,
right: Link<T>,
}
struct Tree<T> {
root: Link<T>,
}
impl<T> Node<T> {
fn new(val: T) -> Self {
Node {
key: val,
left: RefCell::new(None),
right: RefCell::new(None),
}
}
}
impl<T: PartialOrd> Tree<T> {
fn new() -> Self {
Tree {
root: RefCell::new(None),
}
}
fn add(&self, val: T) {
let mut next = self.root.borrow();
let node = Box::new(Node::new(val));
match next.as_ref() {
None => {
self.root.replace(Some(node));
()
}
Some(root_ref) => {
let mut prev = root_ref;
let mut cur: Option<&Box<Node<T>>> = Some(root_ref);
while let Some(node_ref) = cur {
prev = node_ref;
if node.key < node_ref.key {
next = node_ref.left.borrow();
} else {
next = node_ref.right.borrow();
}
cur = next.as_ref();
}
if node.key < prev.key {
prev.left.replace(Some(node));
} else {
prev.right.replace(Some(node));
}
}
}
}
}
fn main() {}
我不明白为什么next
变量的寿命不足:
error[E0597]: `next` does not live long enough
--> src/main.rs:36:15
|
36 | match next.as_ref() {
| ^^^^ borrowed value does not live long enough
...
60 | }
| - `next` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
error[E0597]: `next` does not live long enough
--> src/main.rs:51:27
|
51 | cur = next.as_ref();
| ^^^^ borrowed value does not live long enough
...
60 | }
| - `next` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
next
在add
函数的整个范围内有效,并且我认为在删除next
之前,删除包含对其引用的其他变量。
编译器说"values in a scope are dropped in the opposite order they are created"
,表明存在另一种声明变量和解决此问题的方法,但我不知道如何。
答案 0 :(得分:1)
我看到的问题是,为了更新树的叶节点,您不仅需要保留对每个中间步骤的引用,还必须保留对每个中间步骤的引用,因为到根节点的所有链接都必须保持活动状态。正在更新值。而Rust的一生都无法做到这一点。
也就是说,Rust无法在循环中做到这一点,但可以在递归函数中做到这一点,并且最好使用递归函数来实现树。
自然地,您的递归结构是<script type="text/javascript">
result = "helloworld"
document.getElementById('<%= Label1.ClientID %>').innerHTML = result.substring(0,5);
</script>
,而不是Node
,但是这样的方法可以工作(有很多方法可以使借用工作):
Tree
然后,在impl<T: PartialOrd> Node<T> {
fn add(&self, val: T) {
let mut branch = if val < self.key {
self.left.borrow_mut()
} else {
self.right.borrow_mut()
};
if let Some(next) = &*branch {
next.add(val);
return;
}
//Separated from the if let so that branch is not borrowed.
*branch = Some(Box::new(Node::new(val)));
}
}
中将工作转发给该工作。
如其他人所述,如果您摆脱了impl Tree
vs Tree
和Node
...