0Pricing
Learn Rust Coding · 课时

构建 HashMap

按键插入和查找。

构建 HashMap 是 CoddyKit 上的免费 Learn Rust Coding 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Learn Rust Coding 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Learn Rust Coding 课程共包含 4 节课。

什么是 HashMap?

HashMap 以键值对的形式存储数据。您通过键查找内容,而不是通过索引查找。

可以把它想象成电话簿:姓名(键)映射到电话号码(值)。当您需要根据有意义的键快速查找内容时,HashMaps 非常合适。

导入 HashMap

与 Vec 和 String 不同,HashMap 不在预导入模块中。您必须将它引入作用域。

在文件顶部添加一行 use。这样,整个模块中都可以使用这个名称。

use std::collections::HashMap;

fn main() {
    let scores: HashMap<String, i32> = HashMap::new();
    println!("empty map len: {}", scores.len());
}

插入键值对

使用 insert 添加键及其值。如果该键已经存在,旧值会被替换。

映射必须声明为 mut 才能进行插入。

use std::collections::HashMap;

fn main() {
    let mut scores = HashMap::new();
    scores.insert("Alice", 50);
    scores.insert("Bob", 30);
    println!("{} players", scores.len());
}

类型推断

您很少需要手动写出类型。Rust 会根据前几次 insert 调用推断出 HashMap<&str, i32>。

这里的键是字符串切片,值是整数,所有类型都由使用方式决定。

use std::collections::HashMap;

fn main() {
    let mut ages = HashMap::new();
    ages.insert("Sam", 28);
    ages.insert("Mia", 34);
    println!("Sam is {}", ages["Sam"]);
}

获取值

get 方法会返回一个 Option。如果键存在,您会得到 Some(&value);如果不存在,则会得到 None。

这会要求您安全地处理缺少键的情况。

use std::collections::HashMap;

fn main() {
    let mut scores = HashMap::new();
    scores.insert("Alice", 50);
    match scores.get("Alice") {
        Some(v) => println!("score: {}", v),
        None => println!("no score"),
    }
}

索引与 get

您可以使用 map[key] 进行索引,但如果键不存在,就会引发恐慌。

当键可能不存在时,请优先使用 get。只有在确定键存在时,才使用索引。

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    m.insert("x", 1);
    // m["y"] would panic!
    let v = m.get("y").copied().unwrap_or(0);
    println!("y = {}", v);
}

更新值

使用已存在的键调用 insert 会覆盖旧值。

该方法会返回之前的值(封装在 Option 中),因此您可以根据需要检查它。

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    m.insert("k", 1);
    let old = m.insert("k", 9);
    println!("old = {:?}, now = {}", old, m["k"]);
}

检查键

使用 contains_key 测试某个键是否存在,而不获取它的值。

它会返回一个普通的 bool,在 if 条件中非常方便。

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    m.insert("on", true);
    if m.contains_key("on") {
        println!("key exists");
    }
}

删除条目

remove 方法会删除一个键,并将其值作为 Option 返回。

如果该键不存在,您会得到 None,因此删除操作始终是安全的。

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    m.insert("a", 1);
    let removed = m.remove("a");
    println!("removed {:?}, len {}", removed, m.len());
}

遍历映射

使用 for 循环遍历 HashMap 时,会按引用产生 (key, value) 元组。

请注意,顺序没有规定,并且可能在不同运行之间发生变化,因为哈希会打乱元素的位置。

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    m.insert("a", 1);
    m.insert("b", 2);
    for (k, v) in &m {
        println!("{} -> {}", k, v);
    }
}

键的所有权

当您插入 String 等拥有所有权的值时,映射会取得该值的所有权。

插入之后,除非先克隆该变量,否则您不能再次使用它。

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    let name = String::from("Alice");
    m.insert(name, 50);
    // name is moved here; m owns it now
    println!("{}", m["Alice"]);
}

快速检查

您想要获取一个值,但对应的键可能不存在。

回顾

您学习了如何创建 HashMap、插入键值对,以及使用 get 或索引查找值。

您还了解了 contains_key、remove、迭代,以及映射如何取得所插入键的所有权。

常见问题解答

「构建 HashMap」课时是免费的吗?

是的 — 「构建 HashMap」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Learn Rust Coding 课程的其余内容,请升级到 CoddyKit PRO。 Learn Rust Coding 课程共包含 4 节课。

「构建 HashMap」这节课中我会学到什么?

按键插入和查找。 你通过在浏览器中直接运行的动手代码来练习 Learn Rust Coding,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Learn Rust Coding 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Learn Rust Coding 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「构建 HashMap」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Learn Rust Coding 课中编写并运行代码吗?

能。每节 Learn Rust Coding 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 构建 HashMap
  2. Entry API 与默认值
  3. 使用 HashSet
  4. 计数和分组
← 返回 Learn Rust Coding