rust与其他编程语言一样支持哈希Map这种数据结构。 HashMap<K, V>定义在rust标准库的collections moduleuse将其引入作用域。 下面演示HashMap最基本的API使用。

HashMap的创建和初始化

下面的代码演示了使用new创建了一个空的HashMap,使用insert向HashMap中添加元素。

1
2
3
4
5
6
7
fn main() {
    use std::collections::HashMap;
    let mut map = HashMap::new();
    map.insert(String::from("k1"), 1);
    map.insert(String::from("k2"), 2);
    println!("{:?}", map); // {"k1": 1, "k2": 2}
}

访问HashMap中的元素

下面的代码演示了使用get方法来从HashMap中获取值:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
fn main() {
    use std::collections::HashMap;
    let mut map = HashMap::new();
    map.insert(String::from("k1"), 1);
    map.insert(String::from("k2"), 2);
    match map.get("k1") {
        Some(n) => println!("{}", n),
        None => println!("not found"),
    }
}

HashMap的get方法返回值是标准库中的Option枚举值,get的结果被装进Option枚举的Some中,如果未能根据key get到值,则get方法返回Option枚举的None

下面的代码演示了使用for循环来遍历HashMap:

1
2
3
4
5
6
7
8
9
fn main() {
    use std::collections::HashMap;
    let mut map = HashMap::new();
    map.insert(String::from("k1"), 1);
    map.insert(String::from("k2"), 2);
    for (key, value) in &map {
        println!("{} : {}", key, value);
    }
}

更新HashMap中的元素

insert方法可以为HashMap插入一个键值对,如果Hash中已经存在相同的键,则与这个键关联的旧值将会被覆盖。 在实际开发中,经常需要写"检查一个键是否存在,如果不存在则插入,如果存在则什么也不错"的逻辑,HashMap提供了一个entry方法可以实现这个逻辑。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
fn main() {
    use std::collections::HashMap;
    let mut map = HashMap::new();
    map.insert(String::from("k1"), 1);
    let v1 = map.entry(String::from("k1")).or_insert(0);
    println!("v1={}", v1);
    let v2 = map.entry(String::from("k2")).or_insert(0);
    println!("v2={}", v2);
    println!("{:?}", map); // {"k1": 1, "k2": 0}
}

entry方法返回的是一个Entry枚举,表示Map中可能存在该键的值也可能不存在值,调用Entry的or_insert表示如果没有则插入,or_insert返回的是插入的新值的可变引用。

rustling

rustling中关于HashMap给了两个练习,都比较简单:

  • exercises/collections/hashmap1.rs 对应的知识点是HashMap的创建和insert
  • collections/hashmap2.rs 对应的知识点是HashMap的entry方法的使用