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

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

问题描述

我想收集对结构的更改并一次应用它们.基本轮廓如下所示:

enum SomeEnum {噗,酒吧,}struct SomeStruct {属性:SomeEnum,next_attrib: Option,}impl SomeStruct {pub fn apply_changes(&mut self) {如果让 Some(se) = self.next_attrib {self.atrib = se;}self.next_attrib = 无;}}

产生以下编译器错误:

<块引用>

error[E0507]: 不能移出借来的内容-->src/lib.rs:13:27|13 |如果让 Some(se) = self.next_attrib {|-- ^^^^ 不能移出借来的内容|||提示:为了防止移动,请使用 `ref se` 或 `ref mut se`

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

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

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

是否有另一种方法可以做到这一点,而不会将 Copy/Clone 特征暴露给枚举的所有用户?

解决方案

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

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

impl SomeStruct {pub fn apply_changes(&mut self) {让 next_attrib = std::mem::replace(&mut self.next_attrib, None);如果让 Some(se) = next_attrib {self.atrib = se;}}}

由于这是一个相对常见的模式,但是,Option 上有一个实用函数来处理您希望获得 Option 并将 Option 设置为 None.Option::take 方法就是你想要的.

impl SomeStruct {pub fn apply_changes(&mut self) {如果让 Some(se) = self.next_attrib.take() {self.atrib = se;}}}

另见:

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`

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.

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

解决方案

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.

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

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

See also:

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

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