- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在用 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 需要?
最佳答案
关键是self.root
和 bt.root
是"place expression" s,而元组不是。 #3 起作用的原因是编译器知道如何“通过”中间表达式以绑定(bind)到原始存储位置。
另一种看待它的方式:非常简单的表达式,如 self.root
它们的特殊之处在于它们看起来和行为都像值(并且具有值类型),但编译器会 secret 地记住它是如何达到该值的,从而允许它返回并获取指向该值读取位置的指针。
判断某物是否为“位置表达式”的简单方法是尝试为其赋值。如果你能做到 expr = some_value;
, 然后 expr
必须是“地方表达”。顺便说一下,这也是为什么你写 &self.root
的原因。 , 你会得到一个指向 self.root
位置的指针正在存储,而不是指向 self.root
副本的指针.
这个“放置表达式”业务不适用于元组,因为它们没有这个属性。要构造一个元组,编译器必须实际读取元组元素的值并将它们 move 或复制到元组的新存储中。这会破坏编译器可能拥有的任何位置关联:这些值从字面上不再是它们以前所在的位置。
最后,你可能想看看 Option::as_ref
, 变成 &Option<T>
进入Option<&T>
.那会让你匹配 (self.root.as_ref(), bt.root.as_ref())
, 模式如 (Some(rt), Some(node))
, 这可能更方便。
关于rust - 为什么在 Rust 元组模式匹配中需要显式借用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50265128/
我是一名优秀的程序员,十分优秀!