rust - 如何移出作为选项的结构字段?

标签 rust copy borrow-checker

我想收集对结构的更改并一次性全部应用。 基本大纲如下所示:

enum SomeEnum {
    Foo,
    Bar,
}

struct SomeStruct {
    attrib: SomeEnum,
    next_attrib: Option<SomeEnum>,
}

impl SomeStruct {
    pub fn apply_changes(&mut self) {
        if let Some(se) = self.next_attrib {
            self.attrib = se;
        }
        self.next_attrib = None;
    }
}

这会产生以下编译器错误:

error[E0507]: cannot move out of borrowed content
  --> src/lib.rs:13:27
   |
13 |         if let Some(se) = self.next_attrib {
   |                     --    ^^^^ cannot move out of borrowed content
   |                     |
   |                     hint: to prevent move, use `ref se` or `ref mut se`

我找到了 Get an enum field from a struct: cannot move out of borrowed content并将 #[derive(Clone, Copy)] 添加到我的枚举定义中。

这可能有效,但我对(隐含地)使用复制感到不舒服,因为这通常也可能发生在较大的数据类型上。

实际所有者永远不会移出结构。

是否有另一种方法可以完成此操作,而不会将Copy/Clone 特征暴露给枚举的所有用户?

最佳答案

从本质上讲,如果 self.attrib 仍由 self.next_atrrib 拥有,则不能将值分配给它。这意味着您需要从 self.next_attrib 中删除值,然后将所有权授予 self.attrib

执行此操作的一种方法是手动替换值。例如,您可以使用 std::mem::replace将值替换为 None 并将当前值的所有权作为 next_attrib。然后你可以取值,如果它是Some(_),你可以把它的内容放在self.attrib中。:

impl SomeStruct {
    pub fn apply_changes(&mut self) {
        let next_attrib = std::mem::replace(&mut self.next_attrib, None);
        if let Some(se) = next_attrib {
            self.attrib = se;
        }
    }
}

由于这是一个相对常见的模式,但是,Option 上有一个实用函数来处理您想要拥有 Option 内容的情况> 并将 Option 设置为 NoneOption::take方法就是你想要的。

impl SomeStruct {
    pub fn apply_changes(&mut self) {
        if let Some(se) = self.next_attrib.take() {
            self.attrib = se;
        }
    }
}

另见:

关于rust - 如何移出作为选项的结构字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52031002/

相关文章:

Rust 不能一次多次借用 `x` 作为可变的

rust - 为什么不能在同一结构中存储值和对该值的引用?

arrays - Go 或 Rust 中的数组数组?

generics - 如何使用 Float 特性访问数字常量?

c++ - 为什么声明复制构造函数不会删除复制赋值运算符,反之亦然?

MongoDB 使用外键将字段复制到另一个集合

rust - match + RefCell = X 活得不够长

reference - 多个生命周期和移动 : assignment to borrowed `x` occurs here

winapi - 使用rust Win32 FFI : User-mode data execution prevention (DEP) violation

linux - 如何复制文件/目录而不更改其属性