gpt4 book ai didi

reference - 编写二叉搜索树时,参数类型 `T` 可能生命周期不够长

转载 作者:行者123 更新时间:2023-11-29 08:35:21 25 4
gpt4 key购买 nike

我正在尝试用 Rust 编写二叉搜索树,但我不明白发生了什么:

enum BST<'a, T: Ord> {
Leaf,
BinTree { value: T, left: &'a mut BST<'a, T>, right: &'a mut BST<'a, T> }
}

impl<'a, T: Ord> BST<'a, T> {
fn new() -> BST<'a, T> {
BST::Leaf
}

fn add(self, val: T) {
match self {
BST::Leaf => self = BST::BinTree {
value: val,
left: &mut BST::<'a, T>::new(),
right: &mut BST::<'a, T>::new()
},
BST::BinTree{value: v, left: l, right: r} => if val < v {
l.add(val);
} else {
r.add(val);
}
}
}
}

fn main() {
}

当我尝试编译它时,出现以下错误:

error[E0309]: the parameter type `T` may not live long enough
--> heap.rs:3:25
|
3 | BinTree { value: T, left: &'a mut BST<'a, T>, right: &'a mut BST<'a, T> }
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
note: ...so that the reference type `&'a mut BST<'a, T>` does not outlive the data it points at
--> heap.rs:3:25
|
3 | BinTree { value: T, left: &'a mut BST<'a, T>, right: &'a mut BST<'a, T> }
| ^^^^^^^^^^^^^^^^^^^^^^^^

好吧,经过大量研究并按照编译器的建议进行操作后,我得出了这段代码:

enum BST<'a, T: Ord + 'a> {
Leaf,
BinTree {
value: T,
left: &'a mut BST<'a, T>,
right: &'a mut BST<'a, T>
}
}

impl<'a, T: Ord + 'a > BST<'a, T> {
fn new() -> BST<'a, T> {
BST::Leaf
}

fn add(&mut self, val: T) {
match *self {
BST::Leaf => *self = BST::BinTree {
value: val,
left: &mut BST::<'a, T>::new() as &'a mut BST<'a, T>,
right: &mut BST::<'a, T>::new() as &'a mut BST<'a, T>
},
BST::BinTree{value: ref v, left: ref mut l, right: ref mut r} => if val < *v {
l.add(val);
} else {
r.add(val);
}
}
}
}

fn main() {
}

但我还是会报错:

error: borrowed value does not live long enough
--> heap.rs:19:16
|
19 | left: &mut BST::<'a, T>::new() as &'a mut BST<'a, T>,
| ^^^^^^^^^^^^^^^^^^^ does not live long enough
20 | right: &mut BST::<'a, T>::new() as &'a mut BST<'a, T>
21 | },
| - temporary value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the body at 15:27...
--> heap.rs:15:28
|
15 | fn add(&mut self, val: T) {
| ____________________________^
16 | | match *self {
17 | | BST::Leaf => *self = BST::BinTree {
18 | | value: val,
... |
27 | | }
28 | | }
| |__^

error: borrowed value does not live long enough
--> heap.rs:20:17
|
20 | right: &mut BST::<'a, T>::new() as &'a mut BST<'a, T>
| ^^^^^^^^^^^^^^^^^^^ does not live long enough
21 | },
| - temporary value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the body at 15:27...
--> heap.rs:15:28
|
15 | fn add(&mut self, val: T) {
| ____________________________^
16 | | match *self {
17 | | BST::Leaf => *self = BST::BinTree {
18 | | value: val,
... |
27 | | }
28 | | }
| |__^

error: aborting due to 2 previous errors

我知道这可以通过使用 Boxes 而不是引用来解决,但我想像这样练习。

最佳答案

如错误消息所述,可以通过添加生命周期限制来修复该特定错误 T: 'a .但是随后您会遇到许多其他错误,因为您尝试做的事情是不合理的:您正在尝试存储对在别处没有所有者的对象的引用。

当你做类似存储 &mut BST::<'a, T>::new() 的事情时在你的节点中,BST::<'a, T>::new()返回一个很快就会被销毁的临时值,因此您不能存储对它的引用并期望它继续存在。

而不是引用,你需要你的节点拥有它的 child 。您可以通过将子类型更改为 left: Box<BST<T>> 来执行此操作并使用 Box::new当您创建一个新的子节点时。执行此操作后,您可以摆脱所有 'a无处不在,不会出现与生命周期相关的错误。

另一个问题是您的 add消耗 self参数,因此调用者将无法再使用它。你应该把它变成&mut self相反,它可以修改调用者拥有的树。

关于reference - 编写二叉搜索树时,参数类型 `T` 可能生命周期不够长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45194762/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com