如何移出选项的结构字段? [英] How do I move out of a struct field that is an Option?

查看:64
本文介绍了如何移出选项的结构字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想收集对结构的更改并立即应用所有更改。
基本轮廓如下:

I want to collect changes to a struct and apply them all at once. The basic outline looks like this:

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;
    }
}

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

which yields the following compiler error:


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`


我发现从结构中获取一个枚举字段:无法移出借用的内容,并在我的枚举的定义中添加了#[derive(Clone,Copy)]

I found Get an enum field from a struct: cannot move out of borrowed content and added #[derive(Clone, Copy)] to my enum's definition.

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

This may work but I feel uncomfortable about (implicitly) using copying since this could generally happen to larger datatypes as well.

真正的所有者永远不会移出结构。

The actual owner is never moved out of the struct.

还有另一种方法可以完成此任务,而不会暴露 Copy / 克隆特质给枚举的所有用户?

Is there another way to accomplish this, without exposing the Copy/Clone traits to all users of the enum?

推荐答案

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

Essentially, you can't assign the value to self.attrib if it's still owned by self.next_atrrib. That means you need to remove the value from self.next_attrib and then give ownership to self.attrib.

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

One way to do this would be to manually replace the value. For instance, you could use std::mem::replace to replace the value with None and take ownership of the current value as next_attrib. Then you can take the value and, if it is Some(_), you can place its content in 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 :: take 方法就是您想要的。

Since this is a relatively common pattern, however, there is a utility function on Option to handle situations where you'd like to take ownership of the contents of an Option and set the Option to None. The Option::take method is what you want.

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

另请参见:

  • How can I swap in a new value for a field in a mutable reference to a structure?

这篇关于如何移出选项的结构字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆