You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rustlings HashMap3任务优化咨询:字符串冗余克隆问题

Rust HashMap字符串克隆优化方案

问题背景

我完成了rustlings课程中的hashmap3.rs练习,但当前实现存在冗余的字符串克隆——每次处理队伍时,.entry()方法和Team结构体初始化各做一次克隆,总共三次内存分配。尝试避免克隆时又碰到Rust的借用规则限制,且HashMap要求key为String而非&String,希望找到更高效的实现方式。

原核心代码:

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
}

优化方案

通过Entry的模式匹配,仅在需要创建新Team时克隆一次字符串,已存在的队伍直接复用,彻底减少冗余克隆:

use std::collections::hash_map::Entry;
use std::collections::HashMap;

#[derive(Debug, PartialEq, Eq)]
struct Team {
    name: String,
    goals_scored: u8,
    goals_conceded: u8,
}

fn build_scores_table(results: String) -> HashMap<String, Team> {
    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();

        // 处理第一个队伍,仅在不存在时克隆name
        let team_1 = match scores.entry(team_1_name) {
            Entry::Occupied(entry) => entry.into_mut(),
            Entry::Vacant(entry) => {
                let name = entry.key().clone();
                entry.insert(Team {
                    name,
                    goals_scored: 0,
                    goals_conceded: 0,
                })
            }
        };
        team_1.goals_scored += team_1_score;
        team_1.goals_conceded += team_2_score;

        // 处理第二个队伍,逻辑同上
        let team_2 = match scores.entry(team_2_name) {
            Entry::Occupied(entry) => entry.into_mut(),
            Entry::Vacant(entry) => {
                let name = entry.key().clone();
                entry.insert(Team {
                    name,
                    goals_scored: 0,
                    goals_conceded: 0,
                })
            }
        };
        team_2.goals_scored += team_2_score;
        team_2.goals_conceded += team_1_score;
    }

    scores
}

优化关键点

  1. 按需克隆:仅当队伍不在HashMap中时,才克隆一次字符串作为Team的name;队伍已存在时直接获取可变引用更新数据,无额外克隆。
  2. 解决借用问题:通过Entry的模式匹配,明确区分已存在/不存在两种情况,避免了所有权和借用的冲突。
  3. 高效所有权利用:将team name的所有权转移到HashMap的key中,仅在创建新Team时克隆key的引用,把内存分配次数从原有的三次降到最多两次(初始字符串转换+一次克隆)。

内容的提问来源于stack exchange,提问作者loki.dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 21:01:04