当前位置: 首页 > 知识库问答 >
问题:

在中展开成员变量时,无法移出借用的内容

萧远
2023-03-14

我试图在Rust中创建一个不相交的集合数据结构。相关代码为:

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来避免这些错误,但是我不能更改每个集合的父集合,因为它们是不可变的。

我读过类似的问题,比如:

  • Rust:“无法移出‘self’,因为它是借来的”错误
  • 无法从中借用文件

这些都不能帮助我解决这个问题。我还尝试过重组函数search以及结构本身来使用Rc

这个错误是什么,我如何修复它?


共有2个答案

云承天
2023-03-14

使用选项::将作为匹配自我。父母亲take(),这是这种情况下的基本习惯用法。

self.parent.unwrap()表达式也会导致错误;为此,您需要解决这样一个事实,即解包消耗;您使用选项::as_mut来编写self.parent.as_mut()。

最后的代码是:

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.take() {
            None => self,
            Some(p) => {
                self.parent = Some(p.find());
                self.parent.as_mut().unwrap()
            }
        }
    }
}

仲涵亮
2023-03-14

这个匹配臂将按值获取枚举变量组件。由于您的类型不可复制,这意味着组件将被移出原始位置。这将使您的原始结构部分未定义-一个大的不生锈。

要解决这个问题,请按照编译器的建议,使用一个引用:

Some(ref mut p) =>

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

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安全系统的另一个核心原则,因为这样一来,编译器就更难保证在何时何地更改内容。

看看这个答案,看看解决这个问题的一种方法。

 类似资料:
  • 我正在制作一个单链表。删除节点时,上一个节点的应成为当前节点的(

  •   - a - addr : rt_i2c_bus_device , rt_i2c_msg ai_addr : addrinfo ai_addrlen : addrinfo ai_canonname : addrinfo ai_family : addrinfo ai_flags : addrinfo ai_next : addrinfo ai_protocol : addrinfo ai_soc

  • 这里列出了所有文档化的结构体和联合体的成员变量,并附带结构或联合所属的文件: - a - addr : rt_i2c_bus_device , rt_i2c_msg ai_addr : addrinfo ai_addrlen : addrinfo ai_canonname : addrinfo ai_family : addrinfo ai_flags : addrinfo ai_next : a

  •   - y - y : rt_device_rect_info

  •   - x - x : rt_device_rect_info xfer : rt_spi_ops

  •   - w - waiting_list : rt_wqueue wakeup : rt_wqueue_node width : rt_device_graphic_info , rt_device_rect_info wktime : rt_alarm , rt_alarm_setup work_current : rt_workqueue work_data : rt_work work_fu