gpt4 book ai didi

pointers - Rust 无法移出解引用指针

转载 作者:行者123 更新时间:2023-11-29 07:52:14 26 4
gpt4 key购买 nike

我尝试运行这段代码:

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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com