Reputation: 515
I have a hashmap for all my states, which is a HashMap<String, Rc<State>>
, and I want to call the current state's member fn init(&mut self)
. But I'm getting an error with the following code:
...
if let Some(state) = self.states.get_mut(state_id) {
(*state).init();
}
...
Here's the error:
src/main.rs:70:25: 70:33 error: cannot borrow immutable borrowed content as mutable
src/main.rs:70 (*state).shutdown();`
afaict from the documentation, the problem is that get_mut
returns a mutable reference to the state, not a reference to a mutable state. So how would I get a reference to a mutable state?
Upvotes: 2
Views: 2773
Reputation: 13792
A fundamental idea in Rust is: either Aliasing or Mutability, but not both.
Aliasing means having multiple active pointers to the same value.
What is Rc<T>
? It's sharing ownership, aliasing a value. Thus Rc<T>
does not allow mutating the value inside.
There is a way around this with Rc
, to use interior mutability with types like either Cell<U>
or RefCell<U>
.
(If you write a multithreaded program, you'd use Arc
for thread safe shared ownership / aliasing, and you could use Mutex<U>
for thread safe interior mutability instead.)
Rc<Cell<U>>
allows mutating U
by only allowing write-in and read-out, but no pointers to the inner U
value. No pointers, no aliasing!
Rc<RefCell<U>>
allows mutating by the method .borrow_mut()
that will keep a borrow count at runtime and dynamically make sure that any mutable borrow is exclusive. No aliasing, you have mutability!
Links
Upvotes: 6