-
In question https://github.com/rust-lang/rustlings/blob/main/exercises/11_hashmaps/hashmaps3.rs you have to do 3 straitforward things to each of the two teams (get the existing scores or add new ones, if not yet present and update the two scores). let team_1 = scores.entry(team_1_name).or_insert_with(TeamScores::default);
team_1.goals_scored += team_1_score;
team_1.goals_conceded += team_2_score;
// Similarly for the second team.
let team_2 = scores.entry(team_2_name).or_insert_with(TeamScores::default);
team_2.goals_scored += team_2_score;
team_2.goals_conceded += team_1_score; In any other language and production code i would try (DRY) to extract the 3 fiddely lines into a helper method and just call the helper method twice. (and let the compiler inline it for me). In Rust I tried, but did not manage to get it working. Any Idea, how to do something like this? fn add_single_team_game_result(scores : &mut HashMap<&str, TeamScores>, team_name : &str, scored : u8, conceded : u8)
{
let team = scores.entry(team_name).or_insert_with(TeamScores::default);
team.goals_scored += scored;
team.goals_conceded += conceded;
} ... and in the main method just 2 lines instead of 6: add_single_team_game_result(&scores, team_1_name, team_1_score, team_2_score);
add_single_team_game_result(&scores, team_2_name, team_2_score, team_1_score); I fiddeled with livetime annotations and mutability but could not get this to work. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
To make it work in Rust, there are 2 solutions: Solution 1 (intermediate but efficient)You need to add the lifetime annotation fn add_single_team_game_result<'a>(
scores: &mut HashMap<&'a str, TeamScores>,
team_name: &'a str,
scored: u8,
conceded: u8,
) {
let team = scores.entry(team_name).or_default();
team.goals_scored += scored;
team.goals_conceded += conceded;
} Then you need to pass Solution 2 (easy but inefficient)You might be confused by solution 1 if you aren't familiar with lifetimes yet. fn add_single_team_game_result(
scores: &mut HashMap<String, TeamScores>,
team_name: String,
scored: u8,
conceded: u8,
) {
let team = scores.entry(team_name).or_default();
team.goals_scored += scored;
team.goals_conceded += conceded;
} This code uses You need to convert the team name to add_single_team_game_result(
&mut scores,
team_1_name.to_string(),
team_1_score,
team_2_score,
); Finally, you need to adjust the signature of the Working with owned objects is in general easier. But keep in mind that this solution isn't efficient since we are allocating a Code in MarkdownBTW, for sharing code snippets in Markdown, please use the following for syntax highlighting: ```rust I edited your question to use this syntax :) |
Beta Was this translation helpful? Give feedback.
To make it work in Rust, there are 2 solutions:
Solution 1 (intermediate but efficient)
You need to add the lifetime annotation
'a
to tell the compiler thatteam_name
won't be dropped whilescores
exists.&str
is a pointer to some string in memory. If you drop that string in memory while you still use the pointer as a key in the hash map, then that key would be a dangling pointer.Then you need to pass
&mut scores
in the fu…