- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
以下代码无法编译:
struct Node {
left: Option<Box<Node>>,
right: Option<Box<Node>>,
}
impl Node {
fn new() -> Node {
Node { left: None, right: None, }
}
}
fn init_tree(root: &mut Box<Node>, n: int) {
match n {
0 => {},
_ => {
root.left = Some(box Node::new());
root.right = Some(box Node::new());
init_tree(&mut root.left.unwrap(), n - 1);
init_tree(&mut root.left.unwrap(), n - 1);
}
}
}
fn main() {
let mut root: Box<Node> = box Node::new();
init_tree(&mut root, 10);
}
编译错误是
error: cannot move out of dereference of `&mut`-pointer
init_tree(&mut root.left.unwrap(), n - 1);
^~~~
我该如何解决这个错误?
最佳答案
Rust 编译器不假装出类拔萃的学术成就;它完全按照您告诉的去做,而不是您的意思或想要的。
在这种情况下,当您说 &mut root.left.unwrap()
,你想要的是需要 Option<Box<Node>>
的东西通过可变引用并给你一个 &mut Box<Node>
;但这绝对不是您实际告诉它要做的。
您告诉它要做的是对 root.left.unwrap()
的结果进行可变引用。 ;让我们看看 Option.unwrap
的签名:
fn unwrap(self) -> T
那又如何root.left.unwrap()
是 消耗 root.left
吗? ,取而代之的是 Box<Node>
对象(或者 panic ,如果它是 None
)。然后剩下整个表达式 &mut root.left.unwrap()
生产 &mut Box<Node>
, 和消耗 root.left
因此部分 root
.现在绝对不允许您这样做,因为它会留下 root
需要被销毁,但你只有一个可变的引用它 - 它不是你的销毁。因此错误。
解决方案是不使用unwrap
而是写一个合适的match
表达自己。记住,.unwrap()
只是match self { Some(x) => x, None => panic!(…) }
,这没什么神奇的。
你最终会得到这样的结果:
fn init_tree(root: &mut Node, n: int) {
if n != 0 {
root.left = Some(box Node::new());
root.right = Some(box Node::new());
init_tree(match root.left { Some(box ref mut x) => x, None => unreachable!() }, n - 1);
init_tree(match root.right { Some(box ref mut x) => x, None => unreachable!() }, n - 1);
}
}
(恐怕 box ref mut x
部分有点困惑;它从 &mut T
生成 Box<T>
,box
表示“拆箱值”,ref mut
表示“然后对其进行可变引用”。请记住,所有内容都是从前到后的模式,box
和 &
的含义与它们在外部所做的相反,并且所有内容都是从左到右而不是从右到左阅读. 此外,虽然您可以使用 &mut Box<Node>
,但我建议您使用 &mut Node
,这样可以消除一级间接访问。顺便说一句,如果您仍在使用 &mut Box<Node>
,root.left.as_mut().unwrap()
也可以.)
这可以通过不把东西塞进 root
来改善。立即:
fn init_tree(root: &mut Node, n: int) {
if n != 0 {
let mut left = box Node::new();
let mut right = box Node::new();
init_tree(&mut *left, n - 1);
init_tree(&mut *right, n - 1);
root.left = Some(left);
root.right = Some(right);
}
}
这样看起来就简单多了,&mut *left
从右到左阅读为“解引用 left
(这将使您从 Node
得到一个 Box<Node>
)然后对其进行可变引用(这将使您得到一个 &mut Node
)。
关于rust - 调用 Option::unwrap 时无法移出 `&mut` 指针的取消引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27687872/
我正在做一个项目,我的 android 在这个项目中作为一个网络服务器工作;输入带端口号的 IP 地址,打开 Web 界面,用户可以将文件上传到手机。我想在 Web 界面上显示一些图片,以便我们的界面
我是一名优秀的程序员,十分优秀!