- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我尝试运行这段代码:
impl FibHeap {
fn insert(&mut self, key: int) -> () {
let new_node = Some(box create_node(key, None, None));
match self.min{
Some(ref mut t) => t.right = new_node,
None => (),
};
println!("{}",get_right(self.min));
}
}
fn get_right(e: Option<Box<Node>>) -> Option<Box<Node>> {
match e {
Some(t) => t.right,
None => None,
}
}
得到错误
error: cannot move out of dereference of `&mut`-pointer
println!("{}",get_right(self.min));
^
我不明白为什么我会遇到这个问题,以及我必须使用什么来避免这个问题。
最佳答案
你的问题是get_right()
接受 Option<Box<Node>>
,虽然它真的应该接受 Option<&Node>
并返回 Option<&Node>
以及。调用站点也应适当更改。
这里是解释。 Box<T>
是一个堆分配的盒子。它遵循值语义(也就是说,它的行为类似于普通的 T
,只是它具有关联的析构函数,因此它始终被移动,从不被复制)。因此只传递 Box<T>
进入函数意味着放弃对值的所有权并将其移动到函数中。但是,这不是您真正想要的,也不能在这里做。 get_right()
函数仅查询现有结构,因此不需要所有权。如果不需要所有权,那么引用就是答案。而且,根本不可能移动self.min
。变成一个函数,因为 self.min
通过 self
访问, 这是一个借用的指针。但是,你不能从借来的数据中移出,这是编译器提供的基本安全保证之一。
更改您的 get_right()
定义如下:
fn get_right(e: Option<&Node>) -> Option<&Node> {
e.and_then(|n| n.right.as_ref().map(|r| &**r))
}
然后 println!()
调用应更改为:
println!("{}", get_right(self.min.map(|r| &**r))
这是这里发生的事情。为了获得Option<&Node>
来自 Option<Box<Node>>
您需要将“转换”应用于原始 Option
的内部.有一种方法可以做到这一点,称为 map()
.然而,map()
按值获取目标,这意味着移动 Box<Node>
进入闭包。但是,我们只想借Node
, 所以首先我们需要从 Option<Box<Node>>
开始至 Option<&Box<Node>>
为了 map()
去工作。
Option<T>
有一个方法,as_ref()
, 它通过引用获取目标并返回 Option<&T>
,可能是对选项内部结构的引用。在我们的例子中它将是 Option<&Box<Node>>
.现在这个值可以安全地map()
ped 结束,因为它包含一个引用,并且可以在不影响原始值的情况下自由移动引用。
接下来,map(|r| &**r)
是 Option<&Box<Node>>
的转换至 Option<&Node>
.如果存在闭包参数,则将其应用于选项的内部,否则 None
刚刚通过。 &**r
应该从里到外阅读:&(*(*r))
,也就是说,首先我们取消引用 &Box<Node>
, 获得 Box<Node>
, 然后我们取消引用后者,只获得 Node
, 然后我们引用它,最后得到 &Node
.因为这些引用/取消引用操作是并列的,所以不涉及移动/复制。所以,我们得到了对 Node
的可选引用。 , Option<&Node>
.
你可以看到类似的事情发生在get_right()
中。功能。但是,还有一个新方法,and_then()
叫做。相当于你写的get_right()
最初:如果它的目标是 None
, 它返回 None
, 否则返回 Option
的结果- 返回作为参数传递的闭包:
fn and_then<U>(self, f: |T| -> Option<U>) -> Option<U> {
match self {
Some(e) => f(e),
None => None
}
}
我强烈建议阅读 the official guide这解释了什么是所有权和借用以及如何使用它们,因为它们是 Rust 语言的基础,掌握它们对于提高 Rust 的生产力非常重要。
关于pointers - Rust 无法移出解引用指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26306608/
我正在做一个项目,我的 android 在这个项目中作为一个网络服务器工作;输入带端口号的 IP 地址,打开 Web 界面,用户可以将文件上传到手机。我想在 Web 界面上显示一些图片,以便我们的界面
我是一名优秀的程序员,十分优秀!