Static mutable HashMap

Hello again,

I am writing some code to analyze our codebase. It needs to count all files in a directory structure (recursive), based on file extension. I declare a lazy static HashSet and HashMap like so:

lazy_static!{
    static  ref EXTS: Mutex<HashSet<OsString>> = Mutex::new(HashSet::new());
    static  ref FILE_COUNT: Mutex<HashMap<OsString, u32>> = Mutex::new(HashMap::new());
}

I am able to put the extensions in the HashSet:

       EXTS.lock().unwrap().insert(ext_name.clone());

but when I try to work with the hash map, I get an error that it is not mutable:

        let exts = FILE_COUNT.lock().unwrap();

        let count = exts.entry(ext_name.clone()).or_default();
        *count = *count +1;

error[E0596]: cannot borrow `exts` as mutable, as it is not declared as mutable
  --> src\main.rs:49:21
   |
47 |         let exts = FILE_COUNT.lock().unwrap();
   |             ---- help: consider changing this to be mutable: `mut exts`
48 |
49 |         let count = exts.entry(ext_name.clone()).or_default();
   |                     ^^^^ cannot borrow as mutable

What is the difference between the HashMap and HashSet behavior? How can I solve this.

Thanks.

When you bind the MutexGuard to a variable, the variable must be mutable:

let mut exts = FILE_COUNT.lock().unwrap();

This wasn't required in your HashSet example because you didn't use a variable for the guard; it was just a temporary value.

1 Like