我在Rust中实现了一个双缓冲区,所以当我获得当前缓冲区时,它会执行self.buffers[self.index]
。为了简洁起见,我把它变成了一个函数,这样我就可以这样调用它:
pub struct Screen<'a> {
pub canvas: Canvas<'a>,
pub buffers: [Vec<u32>; 2],
pub index: usize,
}
impl<'a> Screen<'a> {
#[inline(always)]
pub fn get_buf<'b>(&'a self) -> &[u32] {
self.buffers[self.index].as_slice()
}
#[inline(always)]
pub fn get_mut_buf<'b>(&mut self) -> &mut [u32] {
self.buffers[self.index].as_mut_slice()
}
pub fn clear(&mut self, color: u32) {
for pixel in self.get_mut_buf().iter_mut() {
*pixel = color;
}
}
pub fn swap_buffers(&mut self) {
self.canvas.data.copy_from_slice(&self.buffers[self.index]);
self.index += 1;
if self.index >= self.buffers.len() {
self.index = 0;
}
}
}
问题是这是无效的:
pub fn swap_buffers(&mut self) {
self.canvas.data.copy_from_slice(self.get_buf());
self.index += 1;
if self.index >= self.buffers.len() {
self.index = 0;
}
}
虽然这不是:
pub fn swap_buffers(&mut self) {
self.canvas.data.copy_from_slice(&self.buffers[self.index]);
self.index += 1;
if self.index >= self.buffers.len() {
self.index = 0;
}
}
有更好的方法吗?
我甚至尝试将真正的缓冲区封装在一个结构(在本例中为Canvas(中,因为我看到了一些可以帮助的地方,因为借用字段而不是整个结构可以解决这样的问题。
在Rust中,不能同时接受同一事物的可变引用和不可变引用。这在书中描述得很好。
基本上在第二种情况下,编译器能够看到.canvas
和.buffers
是不同的东西。
在第一种情况下,get_buf
返回与&self
具有相同生存期的&[u32]
引用,这意味着当调用self.get_buf()
时,它对整个Screen
结构进行不可变的引用。编译器不允许您使用对.canvas
的可变引用,因为它是self
的一部分,并且您已经使用了对self
的不可变引用。