Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

My Rust OR_INSERT Hashmap code to update a struct content works without dereferencing. Why?

From Rust documentation, this count variable wouldn’t work without dereferencing (*)

let text = "hello world wonderful world";

let mut map = HashMap::new();

for word in text.split_whitespace() {
    let count = map.entry(word).or_insert(0);
    *count += 1;
}

println!("{:?}", map);

However, I have the following code which tries to update a u8 variable (i.e team_val.goals_scored ) in a Struct if the key is found in a hashmap. It works without dereferencing. My understanding from the above Rust documentation was I need to dereference the team_val.goals_scored in order to update the content of the struct which is also a value for the hash map. Whelp!

My code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

#[derive(Debug)]
struct Team {
    name: String,
    goals_scored: u8,
    goals_conceded: u8,
}

fn build_scores_table(results: String) -> HashMap<String, Team> {
    // The name of the team is the key and its associated struct is the value.
    let mut scores: HashMap<String, Team> = HashMap::new();

    for r in results.lines() {
        let v: Vec<&str> = r.split(',').collect();
        let team_1_name = v[0].to_string();
        let team_1_score: u8 = v[2].parse().unwrap();
        let team_2_name = v[1].to_string();
        let team_2_score: u8 = v[3].parse().unwrap();

        // TODO: Populate the scores table with details extracted from the
        // current line. Keep in mind that goals scored by team_1
        // will be number of goals conceded from team_2, and similarly
        // goals scored by team_2 will be the number of goals conceded by
        // team_1.

        let mut team_1_struct= Team {
            name: team_1_name.clone(),
            goals_scored: team_1_score,
            goals_conceded: team_2_score
        };

        let mut team_2_struct= Team {
            name: team_2_name.clone(),
            goals_scored: team_2_score,
            goals_conceded: team_1_score
        };

        if scores.contains_key(&team_1_name) {
            let team_val = scores.entry(team_1_name.clone()).or_insert(team_1_struct);
            println!("Yooo {:#?}",team_val);

            team_val.goals_scored +=team_1_score;
            team_val.goals_conceded += team_2_score;
        } else {
            scores.insert(team_1_name,team_1_struct);
        }

        if scores.contains_key(&team_2_name) {
            let team_val = scores.entry(team_2_name.clone()).or_insert(team_2_struct);
            println!("Yooo {:#?}",team_val);

            team_val.goals_scored +=team_2_score;
            team_val.goals_conceded += team_1_score;
        } else {
            scores.insert(team_2_name,team_2_struct);
        }

        
    }
    scores
}

>Solution :

Rust does some automatic dereferencing, described here. We can see the difference between the documentation code and what you wrote:

// This
*count += 1
// versus this
team_val.goals_scored += team_1_score
        ^--- Causes an automatic dereferencing

If you’re coming from C I think this documentation may be even clearer.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading