沙沙声课程的正确答案,但不满意

lok*_*dev 7 string hashmap rust

这是对最高的尼维奥斯的抱怨,但我解决了沙沙声课程中的一项任务,我相信这不是最佳解决方案 - 甚至不是一个好的解决方案。

任务:https://github.com/rust-lang/rustlings/blob/main/exercises/hashmaps/hashmaps3.rs

我的解决方案(仅相关位):

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();

        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;

        let team_2 = scores.entry(team_2_name.clone()).or_insert(Team {
            name: team_2_name.clone(),
            goals_scored: 0,
            goals_conceded: 0,
        });
        team_2.goals_scored += team_2_score;
        team_2.goals_conceded += team_1_score;
    }
    scores
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,我.entry()在方法内部和团队结构中克隆字符串(两次!)。我尝试不使用它,但它不起作用(借用东西)并使用&但它不高兴,因为它期望String- 不&String

Mas*_*inn 3

不确定到底是什么不起作用?您可以移动到第二个使用站点,它工作正常:

        let team_1 = scores.entry(team_1_name.clone()).or_insert(Team {
            name: team_1_name,
            goals_scored: 0,
            goals_conceded: 0,
        });
        team_1.goals_scored += team_1_score;
        team_1.goals_conceded += team_2_score;
Run Code Online (Sandbox Code Playgroud)

如果您希望在成功案例中进行零克隆(团队已经有一个条目),则代码不太性感,但它也可以很好地编译:

        if let Some(t) = scores.get_mut(&team_1_name) {
            t.goals_scored += team_1_score;
            t.goals_conceded += team_2_score;
        } else {
            scores.insert(team_1_name.clone(), Team {
                name: team_1_name,
                goals_scored: team_1_score,
                goals_conceded: team_2_score,
            });
        }
Run Code Online (Sandbox Code Playgroud)

从技术上讲,我们甚至可以删除初始的to_string并且在命中情况下不进行分配(显然这意味着在无命中情况下进行两次分配):

        let team_1_name = v[0];
        let team_1_score: u8 = v[2].parse().unwrap();
        // ...
        if let Some(t) = scores.get_mut(team_1_name) {
            t.goals_scored += team_1_score;
            t.goals_conceded += team_2_score;
        } else {
            scores.insert(team_1_name.to_string(), Team {
                name: team_1_name.to_string(),
                goals_scored: team_1_score,
                goals_conceded: team_2_score,
            });
        }
Run Code Online (Sandbox Code Playgroud)

name或者,从结构中删除Team,它并不是真正有价值,因为您拥有哈希映射键。尽管此时您不再拥有Team结构,因此可能应该将其重命名为例如Scoreor Goals(并且您可以从左侧的两个成员中删除前缀)。