gpt4 book ai didi

rust - 在 &mut self 方法中展开成员变量时无法移出借用的内容

转载 作者:行者123 更新时间:2023-11-29 07:50:44 27 4
gpt4 key购买 nike

我试图在 Rust 中创建一个 Disjoint-Set 数据结构。相关代码为:

pub struct Set<'a, T: 'a> {
rank: u32,
value: T,
parent: Option<&'a mut Set<'a, T>>,
}

impl<'a, T> Set<'a, T> {
pub fn find(&'a mut self) -> &'a mut Set<'a, T> {
match self.parent {
None => self,
Some(mut p) => {
self.parent = Some(p.find());
self.parent.unwrap()
}
}
}
}

我得到的错误是:

error[E0507]: cannot move out of borrowed content
--> src/main.rs:9:15
|
9 | match self.parent {
| ^^^^ cannot move out of borrowed content
10 | None => self,
11 | Some(mut p) => {
| ----- hint: to prevent move, use `ref p` or `ref mut p`

error[E0507]: cannot move out of borrowed content
--> src/main.rs:13:17
|
13 | self.parent.unwrap()
| ^^^^ cannot move out of borrowed content

我不确定我是否完全理解借用检查器,但我正在使用引用来避免获取结构本身的所有权,以便它们可以被指向和重新分配,类似于您在其他语言中的方式。

我可以通过删除 mut 来避免这些错误来自结构中的引用,但是我无法更改每个集合的父级,因为它们是不可变的。

我已经阅读过类似的问题,例如:

这些并不能帮助我弄清楚如何解决这个问题。我也试过重组功能 find以及要使用的结构本身 Rc<RefCell<Set>>Box<Set>但我总是以同样的错误告终。

这是什么错误,我该如何解决?

最佳答案

这个匹配臂将按值获取枚举变体组件。由于您的类型不可复制,这意味着该组件将被移出原来的位置。这将使您的原始结构部分未定义——这是 Rust 中的一个大禁忌。

要解决这个问题,请按照编译器的建议取而代之:

Some(ref mut p) =>

接下来,不要将结果存储在 Option 中然后立即将其取回,而是尝试将引用保存在变量中,将其放入 Option并返回:

let z = p.find();
self.parent = Some(z);
z

这导致了整个想法的核心问题:

error[E0499]: cannot borrow `*z` as mutable more than once at a time
--> src/main.rs:14:17
|
13 | self.parent = Some(z);
| - first mutable borrow occurs here
14 | z
| ^ second mutable borrow occurs here
15 | }
| - first borrow ends here

您正在尝试存储一个可变引用返回它。这意味着将有多个并发的可变引用指向同一个项目(也称为别名)。防止这种情况是 Rust 安全系统的另一个核心原则,因为这样一来,编译器就很难保证何时何地发生变化。

查看 this answer了解一种解决该问题的方法。

关于rust - 在 &mut self 方法中展开成员变量时无法移出借用的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28194335/

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