替换Rust中的值导致“无法移出借用的内容”

时间:2018-10-27 18:55:00

标签: rust borrow-checker

我正在尝试构建一个图形引擎,该图形引擎可以使用相当常见的两缓冲区模式。在准备下一个缓冲区(current_buffer的同时显示一个缓冲区(next_buffer),然后将下一个缓冲区移至当前缓冲区,然后由新缓冲区重新填充,重复该操作。

我知道还有{strong> 个其他有关cannot move out of borrowed content错误的问题,因此我花了一段时间研究到目前为止可以找到的所有内容,然后才求助于问这个问题。

这是我的代码:

pub fn update(&mut self, dt: f64) {
    if self.is_change_buffer {
        self.current_buffer = self.next_buffer;
        self.next_buffer = Buffer { ... }; // New buffer
    }
}

我在将self.next_buffer移至self.current_buffer时遇到了问题,考虑到self.current_buffer = self.next_buffer会违反“一个所有者”原则,这是可以理解的。 如何告诉借阅检查器我不打算别名self.next_buffer,而是要移动别名,并在其上放置新内容?

我正在使用的框架的一个警告是update() 的功能签名必须是

pub fn (&mut self, dt: f64) -> ()

此外,无法克隆Buffer 。由于Buffer的存储方式,克隆它们将是非常昂贵的操作,因此实际上无法在每次屏幕刷新时完成。

2 个答案:

答案 0 :(得分:4)

  

我如何告诉借阅检查器我不打算别名self.next_buffer,而是想移动它,并在它的位置放些新东西?

借用检查器没有抱怨别名–抱怨是因为您将字段移出了仅借用的结构,这是不允许的。但是,允许移出并立即用新值 替换,并且有一个专用于此用例的专用功能称为std::mem::replace()。使用此功能,您的代码将变为

self.current_buffer = mem::replace(&mut self.next_buffer, Buffer { ... });

答案 1 :(得分:1)

可能最简单的解决方案是使用std::mem::swap

std::mem::swap(&mut self.next_buffer, &mut self.current_buffer);
self.next_buffer = Buffer { ... }; // New buffer

您也可以先分配,然后再交换,但是我发现这种方式更自然。