在此示例中,为什么我可以在匹配表达式中取消引用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)
}
我认为,除了match语句之外,代码的作用并不重要-除非那当然是我困惑的根源。
我也很好奇匹配表达式如何处理解引用的值。具体来说,由于match表达式看到的是一个BinaryTree
类型的值(没有任何引用),为什么match表达式不尝试拥有所有权?更一般而言,Rust的match
如何解释解引用的指针和值之间的区别?
答案 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)
}
}
}
但不需要所有参考。
另请参阅: