刚学Rust,开发一个项目。前一段时间问了这个问题,然后开始写代码。目前写了一点测试,搞明白了一点(以前是一点都不懂)。当初的问题就是要不要Arc<Mutex<T>>,还是Rc<RefCell<T>>就可以。
前面说的这个项目是一个单线程。全部代码太长,就写一个我觉得可能有问题的部分。还有数据结构和算法。这个进程里面有一个主要的类,叫Manager,里面管理一些个传感器。
groups: Rc<RefCell<HashMap<i32, Rc<RefCell<Vec<Sensor>>>>>>;
首先,构建这个groups时候肯定需要borrow_mut。这个可以不管,因为之后就不改变这个HashMap的结构了。后面需要处理一些消息,比如读取传感器的信息,传感器发过来信息,都是单线程的。现在看这个需求,就是传感器通知出问题了,要调用重新设置的函数
// 通过在vec里面的位置来获得这个Sensor,然后设置它
async fn setup_sensor_in_group(group: Rc<RefCell<Vec<Sensor>>>, index: usize) {
let sensor = group.borrow_mut()[index];
sensor.setup().await;
...
match sensor.something.clone() {
Some(good) => {
let agroup = Rc::clone(&group);
task::spawn(async move {
let _ = good.on_whatever().await; //等待传感器出问题
setup_sensor_in_group(agroup, index);
}
}
}
}
总的来说,我的目的是,如果想修改容器里面的某一个传感器(传感器需要重置),就想通过manager的groups获得vec,然后为了修改vec里面的传感器,知道它的下标,就可以修改。我觉得问题在于,为了修改vec的一个元素,我borrow_mut了这个向量。如果这个函数顺利完成,我感觉borrow_mut结束,是没有问题的。但是可能在之后await的时候没有完成,这个时候,另一个传感器坏了,再次调用了这个函数,为的是重制另一个传感器,但是这次还是可能活的同一个vec。
是不是有这个问题?
如果有,能否把重置的函数写成只需要一个传感器?我感觉简化的问题描述就是,要安全修改vec<T>里面的元素。修改的过程是async, 需要await,然后可能会再次获得这个vec来修改另一个元素。
--
FROM 72.197.247.*