Possible improvement for hashmaps3
Problem & possible solution
hashmaps3 plays a scores table using scores: HashMap<String, Team>, where Team: { name: String, … } — both the key and the value describe the team name, leading to the ownership puzzle mentioned in #1074. (See below)
I think we should refactor the map: “team name ↦ scores” or “team ↦ scores”, instead of “team name ↦ team and scores”.
// After refactoring
let board_1 = scores.entry(team_1_name)
.or_insert(ScoreBoard {
goals_scored: 0,
goals_conceded: 0,
});
board_1.goals_scored += team_1_score;
board_1.goals_conceded += team_2_score;
The ownership puzzle
To be specific, there are two solutions here currently.
-
Use
scores.entry(…).or_insert(…).Graceful, but most of the clones are redundant. (Only the first time is necessary.)
let team_1 = scores.entry(team_1_name.clone()) .or_insert(Team { name: team_1_name.clone(), goals_scored: 0, goals_conceded: 0, }); team_1.goals_scored += team_1_score; team_1.goals_conceded += team_2_score;Remark: If you don’t clone for
entry(), you have nothing to setnameinor_insert(). -
Manually get, check and insert.
It only clones when necessary, but becomes more complicated.
let team_2 = match scores.get_mut(&team_2_name) { Some(team) => team, None => { scores.insert( team_2_name.clone(), Team { name: team_2_name.clone(), goals_scored: 0, goals_conceded: 0, }, ); scores.get_mut(&team_2_name).unwrap() } }; team_2.goals_scored += team_2_score; team_2.goals_conceded += team_1_score;
Or using if let.
Besides, storing two team names for each team can be confusing. If two names conflict with each other, which should be taken?
Related: #1160
I believe this merged PR closes this issue: https://github.com/rust-lang/rustlings/pull/1547
Thank you for remind me! I agree. Let's close it.