新建一个哈希 map

  1. use std::collections::HashMap;
  2. let mut scores = HashMap::new();
  3. scores.insert(String::from("Blue"), 10);
  4. scores.insert(String::from("Yellow"), 50);

像 vector 一样,哈希 map 将它们的数据储存在上。
如果 key 和 value 分别在两个 vector 中,可以使用 zip 方法来创建一个元组的迭代器。

  1. use std::collections::HashMap;
  2. let teams = vec![String::from("Blue"), String::from("Yellow")];
  3. let initial_scores = vec![10, 20];
  4. let mut scores: HashMap<_, _> =
  5. teams.into_iter().zip(initial_scores.into_iter()).collect();

这里 HashMap<_, _> 类型注解是必要的,因为可能 collect 为很多不同的数据结构,而除非显式指定否则 Rust 无从得知你需要的类型。

所有权

对于像 i32 这样的实现了 Copy trait 的类型,其值可以拷贝进哈希 map。对于像 String 这样拥有所有权的值,其值将被移动而哈希 map 会成为这些值的所有者。

  1. use std::collections::HashMap;
  2. let field_name = String::from("Favorite color");
  3. let field_value = String::from("Blue");
  4. let mut map = HashMap::new();
  5. map.insert(field_name, field_value);
  6. // 这里 field_name 和 field_value 不再有效,
  7. // 尝试使用它们看看会出现什么编译错误!

访问 map 中的值

  1. use std::collections::HashMap;
  2. let mut scores = HashMap::new();
  3. scores.insert(String::from("Blue"), 10);
  4. scores.insert(String::from("Yellow"), 50);
  5. let team_name = String::from("Blue");
  6. let score = scores.get(&team_name); // Some(10)
  7. // -- snip --
  8. use std::collections::HashMap;
  9. let mut scores = HashMap::new();
  10. scores.insert(String::from("Blue"), 10);
  11. scores.insert(String::from("Yellow"), 50);
  12. for (key, value) in &scores {
  13. println!("{}: {}", key, value);
  14. }

更新 map

覆盖

  1. use std::collections::HashMap;
  2. let mut scores = HashMap::new();
  3. scores.insert(String::from("Blue"), 10);
  4. scores.insert(String::from("Blue"), 25);
  5. println!("{:?}", scores);

只在键没有对应值时插入

  1. use std::collections::HashMap;
  2. let mut scores = HashMap::new();
  3. scores.insert(String::from("Blue"), 10);
  4. scores.entry(String::from("Yellow")).or_insert(50);
  5. scores.entry(String::from("Blue")).or_insert(50);
  6. println!("{:?}", scores);

哈希 map 有一个特有的 API,叫做 entry,它获取我们想要检查的键作为参数。entry 函数的返回值是一个枚举,Entry,它代表了可能存在也可能不存在的值。Entry 的 or_insert 方法在键对应的值存在时就返回这个值的可变引用,如果不存在则将参数作为新值插入并返回新值的可变引用。

根据旧值更新一个值

  1. use std::collections::HashMap;
  2. let text = "hello world wonderful world";
  3. let mut map = HashMap::new();
  4. for word in text.split_whitespace() {
  5. let count = map.entry(word).or_insert(0);
  6. *count += 1;
  7. }
  8. println!("{:?}", map);