The necessity of using RefCell?

Both docs on Rc and RefCell are using the following example to show "put a RefCell<T> inside shared pointer types to reintroduce mutability":

use std::cell::{RefCell, RefMut};
use std::collections::HashMap;
use std::rc::Rc;

fn main() {
    let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new()));

    {
        let mut map: RefMut<_> = shared_map.borrow_mut();
        map.insert("africa", 92388);
        map.insert("kyoto", 11837);
        map.insert("piccadilly", 11826);
        map.insert("marbles", 38);
    }

    let total: i32 = shared_map.borrow().values().sum();
    println!("{}", total);
}

But since Rc provides the method of get_mut(), so without using RefCell, we can achieve the same thing as above example:

use std::collections::HashMap;
use std::rc::Rc;

fn main() {
    let mut shared_map: Rc<_> = Rc::new(HashMap::new());

    {
        let map = Rc::get_mut(&mut shared_map).unwrap();
        map.insert("africa", 9);
        map.insert("kyoto", 18);
    }

    let total: i32 = shared_map.values().sum();
    println!("map: {:?} total: {}", shared_map, total);
}

So I still don't see the necessary of using RefCell in this example. I know that:

RefCell introduces so called “inner mutability”, that is ability to define mutability in runtime.

But the example does not show that up? Is there a way to update a bit on the example so that it can show the necessary of using RefCell?

Sure, try it out!

use std::collections::HashMap;
use std::rc::Rc;

fn main() {
    let mut shared_map: Rc<_> = Rc::new(HashMap::new());
    let map_view = Rc::clone(&shared_map);

    {
        let map = Rc::get_mut(&mut shared_map).unwrap();
        map.insert("africa", 9);
        map.insert("kyoto", 18);
    }

    let total: i32 = map_view.values().sum();
    println!("map: {:?} total: {}", shared_map, total);
}
1 Like

Oh, I seem know what I'm missing, I'm changing

let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new()));

to

let mut shared_map: Rc<_> = Rc::new(HashMap::new());

From a "immutable" to a "mutable".

And RefCell here is " introducing mutability 'inside' of something immutable". Makes sense now :slight_smile:

Nice add! Thanks!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.