rust_learning/collect/
hashmap.rs

1use std::collections::HashMap;
2
3/// 哈希 map
4pub fn hashmap_def() {
5    // HashMap<K, V> 类型储存了一个键类型 K 对应一个值类型 V 的映射。
6    // 它通过一个 哈希函数(hashing function)来实现映射,决定如何将键和值放入内存中。
7    // 哈希 map 可以用于需要任何类型作为键来寻找数据的情况,而不是像 vector 那样通过索引。
8    let mut scores = HashMap::new();
9
10    scores.insert(String::from("Blue"), 10);
11    scores.insert(String::from("Yellow"), 50);
12
13    let team_name = String::from("Blue");
14    // 程序中通过调用 copied 方法来获取一个 Option<i32> 而不是 Option<&i32>,
15    // 接着调用 unwrap_or 在 scores 中没有该键所对应的项时将其设置为零。
16    // let score = scores.get(&team_name).copied().unwrap_or(0);
17    let score = scores.get(&team_name);
18    match score {
19        Some(score) => println!("{:?}", score),
20        None => println!("None"),
21    }
22
23    // 如果使用scores,则使用权被移动
24    for (k, v) in &scores {
25        println!("{:?},{:?}", k, v)
26    }
27
28    // 对于像 i32 这样的实现了 Copy trait 的类型,其值可以拷贝进哈希 map。
29    // 对于像 String 这样拥有所有权的值,其值将被移动而哈希 map 会成为这些值的所有者
30    let field_name = String::from("Favorite color");
31    let field_value = String::from("Blue");
32
33    let mut map = HashMap::new();
34    map.insert(field_name, field_value);
35    // 这里 field_name 和 field_value 不再有效,
36    // println!("{:?}", field_name);
37
38    // 如果将值的引用插入哈希 map,这些值本身将不会被移动进哈希 map。
39    // 但是这些引用指向的值必须至少在哈希 map 有效时也是有效的。
40
41    //更新
42    let mut scores = HashMap::new();
43    // 覆盖一个值
44    scores.insert(String::from("Blue"), 10);
45    scores.insert(String::from("Blue"), 25);
46    println!("{scores:?}");
47
48    // 只在键没有对应值时插入键值对
49    let mut scores = HashMap::new();
50    scores.insert(String::from("Blue"), 10);
51    // 哈希 map 有一个特有的 API,叫做 entry,它获取我们想要检查的键作为参数。
52    // entry 函数的返回值是一个枚举,Entry,它代表了可能存在也可能不存在的值。
53    scores.entry(String::from("Yellow")).or_insert(50);
54    scores.entry(String::from("Blue")).or_insert(50);
55    println!("{scores:?}");
56
57    // 根据旧值更新一个值
58    let text = "hello world wonderful world";
59
60    let mut map = HashMap::new();
61    for word in text.split_whitespace() {
62        // or_insert 方法返回这个键的值的一个可变引用(&mut V)
63        let count = map.entry(word).or_insert(0);
64        *count += 1;
65    }
66    println!("{map:?}");
67}