Need clarity on making structs mutable

I want to make a struct mutable and place it in a HashMap, and change struct field values via the HashMap. In the code below, line commented as AAA works as a mutable struct, but lines comments as BBB fail to work as mutable struct; Why?

use std::collections::HashMap;

#[derive(Copy, Clone, Eq, Hash, Debug, PartialEq)]
pub struct X {
    pub a: i32,
    pub b: i32,  
}
impl X {
    pub fn new(a: i32, b: i32) -> X {
        X { a, b}
    }
    pub fn modify(&mut self, value: i32) {
            self.b += value;
    }
}

pub fn change_hashmap<'a>(hashmap_to_change: &mut HashMap<i32, X>) {
    
    let c = 2;
    let d = 1;
       
    let mut x = X::new(d, c); // FAIL after insertion into HashMap BBB
    let mut x2 = X::new(d, c); // PASS AAA

    x2.b = 100;
       
    hashmap_to_change.insert(d, x);
}

pub fn main() { 
    let mut hashmap1: HashMap<i32, X> = HashMap::new();
    change_hashmap(&mut hashmap1);
    match hashmap1.get(&(1 as i32)) {
        Some(&structure) => {
            // structure.b = 5; // FAIL
            structure.modify(5 as i32); // FAIL BBB
            println!("structure.b * 4 =: {}", structure.b * 4)
        },
        _ => println!("Don't have structure."),
    }
}
 Compiling playground v0.0.1 (/playground)
warning: variable does not need to be mutable
  --> src/main.rs:22:9
   |
22 |     let mut x = X::new(d, c); // FAIL after insertion into HashMap
   |         ----^
   |         |
   |         help: remove this `mut`
   |
   = note: `#[warn(unused_mut)]` on by default

error[E0596]: cannot borrow `structure` as mutable, as it is not declared as mutable
  --> src/main.rs:36:13
   |
34 |         Some(&structure) => {
   |               --------- help: consider changing this to be mutable: `mut structure`
35 |             // structure.b = 5; // FAIL
36 |             structure.modify(5 as i32); // FAIL
   |             ^^^^^^^^^ cannot borrow as mutable

error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0596`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.

First, you should not use an ampersand in patterns, as that does not mean what you think it means.

Seoncd, to modify the thing you got from the hash map, you must use get_mut.

match hashmap1.get_mut(&1) {
    Some(structure) => {
        structure.b += 5;
        println!("structure.b * 4 =: {}", structure.b * 4)
    },
    _ => println!("Don't have structure."),
}

Thank you! Notably, this teaches me to remember to also look at the Docs when something doesn't work!

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.