Enums 访问装箱嵌套结构中的值

Enums 访问装箱嵌套结构中的值,enums,rust,avl-tree,ownership,Enums,Rust,Avl Tree,Ownership,我是一个非常新的生锈,并希望实现一个AVL树 我使用以下枚举表示我的树: enum AvlTree<T> { Leaf, Node { left: Box<AvlTree<T>>, right: Box<AvlTree<T>>, value: T } } enum AvlTree{ 叶子, 节点{ 左:盒子, 右:盒子, 值:T } } 在实现一个平衡功能时,我

我是一个非常新的生锈,并希望实现一个AVL树

我使用以下枚举表示我的树:

enum AvlTree<T> {
    Leaf,
    Node {
        left: Box<AvlTree<T>>,
        right: Box<AvlTree<T>>,
        value: T
    }
}
enum AvlTree{
叶子,
节点{
左:盒子,
右:盒子,
值:T
}
}
在实现一个平衡功能时,我面临着所有权和借款方面的一些问题

我正在尝试编写一个函数,它接受一个
AvlTree
并返回另一个
AvlTree
。我的第一次尝试是这样的:

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
    }
}
fn余额(树:AvlTree)->AvlTree{
如果让AvlTree::Node{left:t,right:u,value:v}=tree{
如果让AvlTree::Node{left:ref tl,right:ref ul,value:ref vl}=*t{
AvlTree::Leaf//在此处返回新的AvlTree
}否则{
树
}
}否则{
树
}
}
即使使用这个最小的示例,编译器也会返回一个错误:

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                  
错误[E0382]:使用部分移动的值:`tree`
-->平均房价:67:17
|                           
63 |如果让AvlTree::Node{left:t,right:u,value:v}=tree{
|-价值转移到这里
...                            
67 |树
|^^^^^移动后此处使用的值
|                           
=注意:发生移动是因为`(树:AvlTree::Node)。left`的类型为`std::boxed::Box`,它没有实现`Copy`特性
我认为,我正确地理解了错误消息,因为分解
AvlTree::Node
将剥夺树示例的所有权。如何防止这种情况发生?我已经尝试了各种方法并(取消)引用
-变量,但只会遇到更多错误

此外,我想在新结构中使用一些提取的值,如
u
tl
vl
。这可能吗?您是否可以提供一个简单的示例来精确执行此操作?执行函数后,我不需要访问旧树

我认为,我正确地理解了错误消息,因为分解
AvlTree::Node
将剥夺树示例的所有权

是的。如果您以后仍然需要能够使用
,则您需要复制该树:

#[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
    }
}
#[派生(克隆)]
枚举AvlTree{…}
fn余额(树:AvlTree)->AvlTree{
让copy=tree.clone();
如果让AvlTree::Node{left:t,right:u,value:v}=tree{
如果让AvlTree::Node{left:ref tl,right:ref ul,value:ref vl}=*t{
AvlTree::Leaf//在此处返回新的AvlTree
}否则{
复制
}
}否则{
树
}
}
或者使用一个可以快速释放其所有权的助手函数-但我认为没有框模式是不可能的:

#![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
    }
}
#![功能(方框模式)]
impl AvlTree{
fn是左节点(&self)->bool{
如果let&AvlTree::Node{left:ref t,right:ref u,value:ref v}=self{
如果let&box AvlTree::Node{left:ref tl,right:ref ul,value:ref vl}=t{
真的
}否则{
假的
}
}否则{
假的
}
}
}
fn余额(树:AvlTree)->AvlTree{
if tree.is_left_node(){
树叶
}否则{
树
}
}
由于您可能希望使用解构值,因此您可能更喜欢
clone
变量,但另一个变量可能会给您一些额外的想法