是否可以借用一个可更改的HashMap内容的引用,并在不妨碍只读访问的情况下长时间使用它?
这是为了保持一个窗口来了解系统中不同组件的状态,这些组件是独立运行的(通过Tokio),需要被监控。
举个例子。
use std::sync::Arc;
use std::collections::HashMap;
struct Container {
running : bool,
count : u8
}
impl Container {
fn run(&mut self) {
for i in 1..100 {
self.count = i;
}
self.running = false;
}
}
fn main() {
let mut map = HashMap::new();
let mut container = Arc::new(
Box::new(
Container {
running: true,
count: 0
}
)
);
map.insert(0, container.clone());
container.run();
map.remove(&0);
}
这适用于一个Tokio驱动的程序,其中多个操作将异步进行,并且需要对它们的整体状态进行监控。
有 这个问题 可以借用一个临时的可变引用,但这不能作为 run()
函数需要时间来完成。
基于Jmb和Stargateur的建议,重做了这个,以使用一个 RwLock
内部。这些内部可以通过拥有操纵它们的方法来重新设计,但基本的东西在这里。
use std::sync::Arc;
use std::sync::RwLock;
use std::collections::HashMap;
#[derive(Debug)]
struct ContainerState {
running : bool,
count : u8
}
struct Container {
state : Arc<RwLock<ContainerState>>
}
impl Container {
fn run(&self) {
for i in 1..100 {
let mut state = self.state.write().unwrap();
state.count = i;
}
{
let mut state = self.state.write().unwrap();
state.running = false;
}
}
}
fn main() {
let mut map = HashMap::new();
let state = Arc::new(
RwLock::new(
ContainerState {
running: true,
count: 0
}
)
);
map.insert(0, state);
let container = Container {
state: map[&0].clone()
};
container.run();
println!("Final state: {:?}", map[&0]);
map.remove(&0);
}
我所遗漏的最关键的东西是 你可以有一个可改变的引用。或 多个不可更改的引用,而且它们是相互排斥的。我最初的理解是,这两个限制是独立的。