A similar question I posted earlier is here Rust can't modify RefCell in Rc, but completely different.
I want to simulate some natural process, so I have a Simulator
, and a reactor like a NuclearReactor
. The simulator will modify the reactor, and the reactor can reversely influance the simulator by modifying it. One important thing is that the NuclearReactor
is wrapped from somewhere else, the solid_function
must has a inmutable &self
.
So after reading rust book of RefCell
, I wrote something like these, It complies, but crashed.
use std::borrow::BorrowMut;
use std::cell::RefCell;
use std::rc::{Rc, Weak};
pub struct Simulator {
nr: NuclearReactor,
data: Vec<f64>,
}
impl Simulator {
pub fn on_nuclear_data(&mut self, x: i64) {
// modify self
}
pub fn run_simulation(&mut self) {
self.nr.write_simulator();
}
}
pub struct NuclearReactor {
simulator: Option<Weak<RefCell<Simulator>>>,
}
impl NuclearReactor {
pub fn solid_function(&self, x: i64) {
/*
this function `&self` is solid, so I have to use a RefCell to wrap Simulator
*/
}
pub fn write_simulator(&self) {
/*
thread 'main' panicked at 'already borrowed: BorrowMutError'
*/
(*self.simulator.as_ref().unwrap().upgrade().unwrap()).borrow_mut().on_nuclear_data(0);
}
}
pub fn main() {
let nr_ = NuclearReactor {
simulator: None
};
let mut sm_ = Rc::new(RefCell::new(Simulator {
nr: nr_,
data: vec![],
}));
(*sm_).borrow_mut().nr.simulator = Some(Rc::downgrade(&sm_));
(*sm_).borrow_mut().run_simulation();
}
Obviously, the runtime check of borrow_mut
fails.
Actually the NuclearReactor
is my online code, the Simulator
is an offline test, so I wanna modify the NuclearReactor
at a minimal cost to let it run on the offline environment. That's why I have to keep the function solid_function
with an immutable &self
. Changing it to a &mut self
is and then move to-modifying objects
to a seperate function is feasible, but then I have to modify the online code frequently at a high cost. It there anything cool that can solve it ?
Ok, after reading this: http://smallcultfollowing.com/babysteps/blog/2018/11/01/after-nll-interprocedural-conflicts/
I finnaly realized that what I am doing is something like below and rust was helping me avoiding bugs.
Thankfully, pushing
NuclearReactor
's modify to a temp buffer then apply them toSimulator
is just enough to solve my problem.Also, I didn't explain the question clearly (actually I didn't get the point to describe the question until I solved it), so the community can't help me.