我正在尝试创建一个可变Vec
对象池,可以根据需要将其传递给函数,并在不再需要它们时重用(因为我的目标是 WASM,我不想让Vec
s 自己释放和重新分配)。我有一个使用Rc
and的实现RefCell
,我想知道是否有更好(更有效?)的方法来做到这一点。
我当前的代码用于Rc::strong_count
跟踪我是否已分发缓冲区并RefCell
允许对Vec
内部进行可变访问:
use std::{cell::RefCell, rc::Rc};
#[derive(Debug)]
struct BufferPool {
buffers: Vec<Rc<RefCell<Vec<f64>>>>,
buffer_size: usize,
}
impl BufferPool {
fn new() -> Self {
BufferPool {
buffers: vec![],
buffer_size: 3,
}
}
fn add_buffer(&mut self) -> Rc<RefCell<Vec<f64>>> {
self.buffers
.push(Rc::new(RefCell::new(vec![0.; self.buffer_size])));
Rc::clone(&self.buffers[self.buffers.len() - 1])
}
fn get_buffer(&mut self) -> Rc<RefCell<Vec<f64>>> {
for buf in &self.buffers {
// If the Rc count is 1, we haven't loaned the buffer out yet.
if Rc::strong_count(&buf) == 1 {
return Rc::clone(&buf);
}
}
// If we made it here, there's no available buffer, so we need to create one.
self.add_buffer()
}
}
可以使用以下代码测试此代码:
#[test]
fn test_buffers() {
let mut buffers = BufferPool::new();
let buf_cell1 = buffers.get_buffer();
{
let mut buf1 = buf_cell1.borrow_mut();
buf1[0] = 5.5;
}
{
let buf_cell2 = buffers.get_buffer();
let mut buf2 = buf_cell2.borrow_mut();
buf2[1] = 6.6;
}
{
let buf_cell3 = buffers.get_buffer();
let mut buf3 = buf_cell3.borrow_mut();
buf3[2] = 7.7;
}
dbg!(&buffers);
}
这给出了预期的输出:
&buffers = BufferPool {
buffers: [
RefCell {
value: [
5.5,
0.0,
0.0,
],
},
RefCell {
value: [
0.0,
6.6,
7.7,
],
},
],
buffer_size: 3,
}
但是,我正在做的事情似乎效率低下,因为两者Rc
都RefCell::borrow_mut()
在跟踪缓冲区是否已“借出”(因为RefCell
如果它的内容被双重借用,则有能力出错)。此外,从人体工程学上讲,我不能buffers.get_buffer().borrow_mut()
在没有 Rust 抱怨临时值丢失的情况下调用一行代码,这很烦人。
所以,我的问题是:有没有更好的方法来做到这一点?