Shien
Shien

Reputation: 515

How to get mutable struct from HashMap?

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

Answers (1)

bluss
bluss

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

Related Questions