Replacing values in Rust causing “cannot move out of borrowed content” [duplicate]

限于喜欢 提交于 2019-12-14 04:04:12

问题


I'm trying to build a graphics engine that works with the fairly common two-buffer pattern. One buffer (current_buffer) is displayed while the next (next_buffer) is prepared, then the next buffer is moved into the current buffer, and is subsequently repopulated by a new buffer, repeating.

I know there are a lot of other questions about cannot move out of borrowed content errors, so I spent a while looking at all I can find so far before finally resorting to asking this as a question.

Here's my code:

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

I'm running into problems with moving self.next_buffer to self.current_buffer, which is understandable considering that self.current_buffer = self.next_buffer would break the "one owner" principle. How do I tell the borrow checker that I'm not trying to alias self.next_buffer, I'm trying to move it, and put something new in its place?

A caveat due to a framework I'm working with is that the function signature of update() must be:

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

Also, a Buffer cannot be cloned. Because of the way Buffers are stored, cloning them would be an extremely expensive operation, and so cannot practically be done at every screen refresh.


回答1:


How do I tell the borrow checker that I'm not trying to alias self.next_buffer, I'm trying to move it, and put something new in its place?

The borrow checker is not complaining about aliasing – it is complaining because you are moving a field out of a struct that you only borrowed, which is not allowed. However, moving out and immediately replacing with a new value is allowed, and there is a dedicated function for exactly this use case, called std::mem::replace(). With this function, your code becomes

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



回答2:


Probably the easiest solution is to use std::mem::swap:

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

You can also assign first and then swap, but I find it more natural this way.



来源:https://stackoverflow.com/questions/53025265/replacing-values-in-rust-causing-cannot-move-out-of-borrowed-content

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!