【发布时间】:2018-05-10 03:42:26
【问题描述】:
我正在用 Rust 写一棵二叉树,借用检查器真的让我很困惑。这里是a minimal example that reproduces the problem。
二叉树定义如下:
struct NonEmptyNode;
pub struct BinaryTree {
root: Option<NonEmptyNode>,
}
借用检查器拒绝的代码是:
// Implementation #1
fn set_child_helper(&self, bt: &Self, setter: fn(&NonEmptyNode, &NonEmptyNode)) -> bool {
match (self.root, bt.root) {
(Some(ref rt), Some(ref node)) => {
setter(rt, node);
true
}
_ => false,
}
}
错误信息是
error[E0507]: cannot move out of borrowed content
--> src/main.rs:10:16
|
10 | match (self.root, bt.root) {
| ^^^^ cannot move out of borrowed content
error[E0507]: cannot move out of borrowed content
--> src/main.rs:10:27
|
10 | match (self.root, bt.root) {
| ^^ cannot move out of borrowed content
要使其工作,必须将代码修改为:
// Implementation #2
fn set_child_helper(&self, bt: &Self, setter: fn(&NonEmptyNode, &NonEmptyNode)) -> bool {
match (&self.root, &bt.root) {
// explicit borrow
(&Some(ref rt), &Some(ref node)) => {
// explicit borrow
setter(rt, node);
true
}
_ => false,
}
}
如果我在没有显式借用的情况下一次对一个变量进行模式匹配,则借用检查器根本不会抱怨:
// Implementation #3
fn set_child_helper(&self, bt: &Self, setter: fn(&NonEmptyNode, &NonEmptyNode)) -> bool {
match self.root {
Some(ref rt) => match bt.root {
// No explict borrow will be fine
Some(ref node) => {
// No explicit borrow will be fine
setter(rt, node);
true
}
_ => false,
},
_ => false,
}
}
为什么实现 #3 不需要显式借用,而实现 #1 需要?
【问题讨论】:
-
巧合的是,在您发布此问题后 仅几个小时,Rust 1.26 已发布,其中包括(除其他很酷的东西)
match模式的自动引用和取消引用语义.这意味着在匹配(&self.root, &bt.root)时,您可以编写(Some(rt), Some(node)),编译器会智能地将rt和node转换为引用。 (playground)
标签: rust pattern-matching move-semantics