如何使用消耗该成员本身的成员方法替换结构的成员?

时间:2019-07-04 07:58:18

标签: rust lifetime ownership

我有一个枚举,其中可能包含一个向量。我实现了一种枚举方法,该方法可以生成一个新的枚举,该枚举可以重用先前枚举中的相同向量(我不想复制该向量)。生成新的枚举后,我将不再使用以前的枚举,因此我将这种方法实现为fn (self)来获得枚举的所有权。

然后,我将枚举放入结构中,我想通过使用刚实现的枚举的方法替换结构中的枚举。但是我遇到了这个错误:

error[E0507]: cannot move out of borrowed content
  --> src/lib.rs:22:18
   |
22 |         self.0 = self.0.get_a_new_foo();
   |                  ^^^^^^ cannot move out of borrowed content

有什么办法可以修复我的代码?

enum Foo {
    A,
    B(Vec<u32>),
}

impl Foo {
    fn get_a_new_foo(self) -> Foo {
        match self {
            Foo::A => Foo::B(vec![]),
            Foo::B(mut v) => {
                let len = v.len() as u32;
                v.push(len - 1);
                Foo::B(v)
            }
        }
    }
}

struct Bar(Foo);
impl Bar {
    fn replace_foo(&mut self) -> () {
        self.0 = self.0.get_a_new_foo();
    }
}

1 个答案:

答案 0 :(得分:2)

您可以使用take_mut板条箱优雅地进行此操作:

struct Bar(Foo);
impl Bar {
    fn replace_foo(&mut self) -> () {
        take_mut::take(&mut self.0, |foo| foo.get_a_new_foo());
    }
}

或者,没有其他依赖性,您可以执行以下操作:

struct Bar(Foo);
impl Bar {
    fn replace_foo(&mut self) -> () {
        let mut tmp = Foo::A;
        std::mem::swap(&mut tmp, &mut self.0);
        tmp = tmp.get_a_new_foo();
        std::mem::swap(&mut tmp, &mut self.0);
    }
}

但是,只有在您可以廉价地构建Foo的“占位符”变体(例如Foo::A)的情况下,它才起作用。

相关问题