Rust 哈希映射

哈希指的就是键值对。

创建一个哈希映射

下面的代码中创建了一个hash映射,rust推导了hashmap的类型:

fn main() {
    use std::collections::HashMap;

    let mut scores = HashMap::new();

    scores.insert(String::from("Blue"), 10);
    scores.insert(String::from("Yellow"), 50);
}

还有一种创建哈希映射的方法,通过zip的方法创建一个元组的数据,然后用collect方法来将动态数组转为hash映射

fn main() {
    use std::collections::HashMap;

    let teams = vec![String::from("Blue"), String::from("Yellow")];
    let initial_scores = vec![10, 50];

    let mut scores: HashMap<_, _> =
        teams.into_iter().zip(initial_scores.into_iter()).collect();
}

HashMap<_, _>不能被省略,需要告知collect数据结构,但是里面 _占位符的数据类型是rust可以推导的,我们可以用 _来标识。

哈希映射与所有权

对于实现了copy trait的类型,例如i32,它们的值会被简单地复制到哈希映射中,而对于String这种持有所有权的值,其值会转移且所有权会转移给哈希映射:

fn main() {
    use std::collections::HashMap;

    let field_name = String::from("Favorite color");
    let field_value = String::from("Blue");

    let mut map = HashMap::new();
    map.insert(field_name, field_value);
    // field_name and field_value are invalid at this point, try using them and
    // see what compiler error you get!
}

可以将引用插入哈希映射中,但是必须保证引用所指向的值的有效性。涉及生命周期的部分之后讨论。

访问哈希映射中的值

通过get方法来获得哈希映射的值:

fn main() {
    use std::collections::HashMap;

    let mut scores = HashMap::new();

    scores.insert(String::from("Blue"), 10);
    scores.insert(String::from("Yellow"), 50);

    let team_name = String::from("Blue");
    let score = scores.get(&team_name);
}

get会返回一个option

可以使用for循环来遍历哈希映射中所有的键值对

fn main() {
    use std::collections::HashMap;

    let mut scores = HashMap::new();

    scores.insert(String::from("Blue"), 10);
    scores.insert(String::from("Yellow"), 50);

    for (key, value) in &scores {
        println!("{}: {}", key, value);
    }
}

更新哈希映射

覆盖旧值

insert可以将旧值覆盖

fn main() {
    use std::collections::HashMap;

    let mut scores = HashMap::new();

    scores.insert(String::from("Blue"), 10);
    scores.insert(String::from("Blue"), 25);

    println!("{:?}", scores);
}

只在键没有对应值时插入数据

or_insert不将值覆盖,会返回Entry键所指向值的可变引用

fn main() {
    use std::collections::HashMap;

    let mut scores = HashMap::new();
    scores.insert(String::from("Blue"), 10);

    scores.entry(String::from("Yellow")).or_insert(50);
    scores.entry(String::from("Blue")).or_insert(50);

    println!("{:?}", scores);
}

基于旧值来更新值

通过count可变引用指向hashmap元素地址,通过解引用操作数字。

fn main() {
    use std::collections::HashMap;

    let text = "hello world wonderful world";

    let mut map = HashMap::new();

    for word in text.split_whitespace() {
        let count = map.entry(word).or_insert(0);
        *count += 1;
    }

    println!("{:?}", map);
}

下一章:Rust 动态数组

动态数组:Vec< T >,T表示泛型。 创建动态数组 fn main() { let v: Vec<i32> = Vec::new();} 创建动态数组的声明需要声明类型,因为数组中没有数据, ...