如何在不取得所有权的情况下替换结构字段的值

How to replace the value of a struct field without taking ownership

(关注

我有一个第三方 API 其中一个结构有一个使用实例的方法和 returns 一个新实例;我想将此 API 包装在我自己的包装器中,并抽象出该结构在操作中使用的细节。

这个例子解释了我想要实现的目标:

// Third-party API
struct Item {
    x: u32,
}

impl Item {
    pub fn increment(self, amount: u32) -> Self {
        Item { x: self.x + amount }
    }
}

// My API
struct Container {
    item: Item,
}

impl Container {
    pub fn increment_item(&mut self, amount: u32) {
        // This line causes "cannot move out of borrowed content" but this is exactly what I want to do
        self.item = self.item.increment(amount);
    }
}

虽然现在我明白了这个错误,但我想知道如何在不取得 Container::increment_item 中的 self 所有权的情况下实现它。

建议的解决方案:

关于如何做的一些想法?还是我在 Rust 中尝试一个不可能的设计?

最简单的方法是使用 Option:

  • 使用 take 取得物品的所有权,
  • 然后分配回来 Some(...).

如果在 Option 为空时发生恐慌,这是绝对安全的。不会发生双重破坏,如果您愿意,容器甚至可以继续使用。

或者在代码中:

// Third-party API
struct Item {
    x: u32,
}

impl Item {
    pub fn increment(self, amount: u32) -> Self {
        Item { x: self.x + amount }
    }
}

// My API
struct Container {
    item: Option<Item>,
}

impl Container {
    pub fn increment_item(&mut self, amount: u32) {
        let item = self.item.take().unwrap();
        self.item = Some(self.item.increment(amount));
    }
}