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:
#[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.