在盒装嵌套结构中访问值
Access values in boxed nested struct
我对 Rust 还很陌生,想实现一个 AVL-Tree。
我正在使用以下枚举来表示我的树:
enum AvlTree<T> {
Leaf,
Node {
left: Box<AvlTree<T>>,
right: Box<AvlTree<T>>,
value: T
}
}
在实现其中一项余额功能时,我在所有权和借用方面遇到了一些问题。
我正在尝试编写一个函数,它需要一个 AvlTree<T>
和 returns 另一个 AvlTree<T>
。我的第一次尝试是这样的:
fn balance_ll(tree: AvlTree<T>) -> AvlTree<T> {
if let AvlTree::Node {left: t, right: u, value: v} = tree {
if let AvlTree::Node {left: ref tl, right: ref ul, value: ref vl} = *t {
AvlTree::Leaf // Return a new AvlTree here
} else {
tree
}
} else {
tree
}
}
即使是这个最小的示例,编译器也会返回错误:
error[E0382]: use of partially moved value: `tree`
--> avl.rs:67:17
|
63 | if let AvlTree::Node {left: t, right: u, value: v} = tree {
| - value moved here
...
67 | tree
| ^^^^ value used here after move
|
= note: move occurs because `(tree:AvlTree::Node).left` has type `std::boxed::Box<AvlTree<T>>`, which does not implement the `Copy` trait
我认为,我对错误消息的理解是正确的,因为 AvlTree::Node
的解构将带走树示例的所有权。我怎样才能防止这种情况发生?我已经尝试了各种方法并(取消)引用 tree
变量,结果却遇到了更多错误。
此外,我想在新结构中使用一些提取的值,如 u
、tl
和 vl
。这可能吗?您能否提供一个最小的例子来做到这一点?执行函数后我不需要访问旧树。
I think, I'm understanding the error message correctly, in that destructuring the AvlTree::Node
will take away the ownership of the tree example.
是的。如果之后您仍然需要能够使用 tree
,则需要复制它:
#[derive(Clone)]
enum AvlTree<T> {...}
fn balance_ll<T: Clone>(tree: AvlTree<T>) -> AvlTree<T> {
let copy = tree.clone();
if let AvlTree::Node { left: t, right: u, value: v } = tree {
if let AvlTree::Node { left: ref tl, right: ref ul, value: ref vl } = *t {
AvlTree::Leaf // Return a new AvlTree here
} else {
copy
}
} else {
tree
}
}
或者使用可以快速释放其所有权的辅助函数 - 但我认为没有盒子模式是不可能的:
#![feature(box_patterns)]
impl<T> AvlTree<T> {
fn is_left_node(&self) -> bool {
if let &AvlTree::Node { left: ref t, right: ref u, value: ref v } = self {
if let &box AvlTree::Node { left: ref tl, right: ref ul, value: ref vl } = t {
true
} else {
false
}
} else {
false
}
}
}
fn balance_ll<T>(tree: AvlTree<T>) -> AvlTree<T> {
if tree.is_left_node() {
AvlTree::Leaf
} else {
tree
}
}
由于您可能想要使用解构值,您可能更喜欢 clone
变体,但也许另一个会给您一些额外的想法。
我对 Rust 还很陌生,想实现一个 AVL-Tree。
我正在使用以下枚举来表示我的树:
enum AvlTree<T> {
Leaf,
Node {
left: Box<AvlTree<T>>,
right: Box<AvlTree<T>>,
value: T
}
}
在实现其中一项余额功能时,我在所有权和借用方面遇到了一些问题。
我正在尝试编写一个函数,它需要一个 AvlTree<T>
和 returns 另一个 AvlTree<T>
。我的第一次尝试是这样的:
fn balance_ll(tree: AvlTree<T>) -> AvlTree<T> {
if let AvlTree::Node {left: t, right: u, value: v} = tree {
if let AvlTree::Node {left: ref tl, right: ref ul, value: ref vl} = *t {
AvlTree::Leaf // Return a new AvlTree here
} else {
tree
}
} else {
tree
}
}
即使是这个最小的示例,编译器也会返回错误:
error[E0382]: use of partially moved value: `tree`
--> avl.rs:67:17
|
63 | if let AvlTree::Node {left: t, right: u, value: v} = tree {
| - value moved here
...
67 | tree
| ^^^^ value used here after move
|
= note: move occurs because `(tree:AvlTree::Node).left` has type `std::boxed::Box<AvlTree<T>>`, which does not implement the `Copy` trait
我认为,我对错误消息的理解是正确的,因为 AvlTree::Node
的解构将带走树示例的所有权。我怎样才能防止这种情况发生?我已经尝试了各种方法并(取消)引用 tree
变量,结果却遇到了更多错误。
此外,我想在新结构中使用一些提取的值,如 u
、tl
和 vl
。这可能吗?您能否提供一个最小的例子来做到这一点?执行函数后我不需要访问旧树。
I think, I'm understanding the error message correctly, in that destructuring the
AvlTree::Node
will take away the ownership of the tree example.
是的。如果之后您仍然需要能够使用 tree
,则需要复制它:
#[derive(Clone)]
enum AvlTree<T> {...}
fn balance_ll<T: Clone>(tree: AvlTree<T>) -> AvlTree<T> {
let copy = tree.clone();
if let AvlTree::Node { left: t, right: u, value: v } = tree {
if let AvlTree::Node { left: ref tl, right: ref ul, value: ref vl } = *t {
AvlTree::Leaf // Return a new AvlTree here
} else {
copy
}
} else {
tree
}
}
或者使用可以快速释放其所有权的辅助函数 - 但我认为没有盒子模式是不可能的:
#![feature(box_patterns)]
impl<T> AvlTree<T> {
fn is_left_node(&self) -> bool {
if let &AvlTree::Node { left: ref t, right: ref u, value: ref v } = self {
if let &box AvlTree::Node { left: ref tl, right: ref ul, value: ref vl } = t {
true
} else {
false
}
} else {
false
}
}
}
fn balance_ll<T>(tree: AvlTree<T>) -> AvlTree<T> {
if tree.is_left_node() {
AvlTree::Leaf
} else {
tree
}
}
由于您可能想要使用解构值,您可能更喜欢 clone
变体,但也许另一个会给您一些额外的想法。