-
| 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
'ato tell the compiler thatteam_namewon't be dropped whilescoresexists.&stris 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 scoresin the fu…