匹配表达式如何解释值与引用?

时间:2018-06-29 20:19:41

标签: reference rust match

在此示例中,为什么我可以在匹配表达式中取消引用t而不在其正上方的行上取消引用?

fn tree_weight_v2(t: &BinaryTree) -> i32 {
    // let x = *t; // if uncommented, error: "Cannot move out of borrowed content"
    match *t {
        BinaryTree::Leaf(payload) => payload,
        BinaryTree::Node(ref left, payload, ref right) => {
            tree_weight_v2(left) + payload + tree_weight_v2(right)
        }
    }
}

#[test]
fn tree_demo_2() {
    let tree = sample_tree();
    assert_eq!(tree_weight_v2(&tree), (1 + 2 + 3) + 4 + 5);
    assert_eq!(tree_weight_v2(&tree), (1 + 2 + 3) + 4 + 5);
    // no error ^ meaning tree_weight_v2 is not taking ownership of tree
}

enum BinaryTree {
    Leaf(i32),
    Node(Box<BinaryTree>, i32, Box<BinaryTree>)
}

fn sample_tree() -> BinaryTree {
    let l1 = Box::new(BinaryTree::Leaf(1));
    let l3 = Box::new(BinaryTree::Leaf(3));
    let n2 = Box::new(BinaryTree::Node(l1, 2, l3));
    let l5 = Box::new(BinaryTree::Leaf(5));

    BinaryTree::Node(n2, 4, l5)
}

playground

我认为,除了match语句之外,代码的作用并不重要-除非那当然是我困惑的根源。

我也很好奇匹配表达式如何处理解引用的值。具体来说,由于match表达式看到的是一个BinaryTree类型的值(没有任何引用),为什么match表达式不尝试拥有所有权?更一般而言,Rust的match如何解释解引用的指针和值之间的区别?

1 个答案:

答案 0 :(得分:0)

let x = *t不起作用,因为它已移出引用。即这意味着,通过取消引用t,您将得到一个BinaryTree(无引用)。 BinaryTree是在函数中借用的,因此将其分配给let x = *t会将其移到x中,这是不可能的,因为它是借用的。

因为match借用了变量,所以匹配确实有效。 match *t不会将其移出,但会借用BinaryTree。这是Rust中的一种特殊语法,借用发生在幕后。您可以想到这一点:

fn tree_weight_v2(t: &BinaryTree) -> i32 {
    match &*t {
        &BinaryTree::Leaf(payload) => payload,
        &BinaryTree::Node(ref left, payload, ref right) => {
            tree_weight_v2(left) + payload + tree_weight_v2(right)
        }
    }
}

但不需要所有参考。


另请参阅: