新建一个哈希 map
use std::collections::HashMap;let mut scores = HashMap::new();scores.insert(String::from("Blue"), 10);scores.insert(String::from("Yellow"), 50);
像 vector 一样,哈希 map 将它们的数据储存在堆上。
如果 key 和 value 分别在两个 vector 中,可以使用 zip 方法来创建一个元组的迭代器。
use std::collections::HashMap;let teams = vec![String::from("Blue"), String::from("Yellow")];let initial_scores = vec![10, 20];let mut scores: HashMap<_, _> =teams.into_iter().zip(initial_scores.into_iter()).collect();
这里 HashMap<_, _> 类型注解是必要的,因为可能 collect 为很多不同的数据结构,而除非显式指定否则 Rust 无从得知你需要的类型。
所有权
对于像 i32 这样的实现了 Copy trait 的类型,其值可以拷贝进哈希 map。对于像 String 这样拥有所有权的值,其值将被移动而哈希 map 会成为这些值的所有者。
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 和 field_value 不再有效,// 尝试使用它们看看会出现什么编译错误!
访问 map 中的值
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); // Some(10)// -- snip --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);}
更新 map
覆盖
use std::collections::HashMap;let mut scores = HashMap::new();scores.insert(String::from("Blue"), 10);scores.insert(String::from("Blue"), 25);println!("{:?}", scores);
只在键没有对应值时插入
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);
哈希 map 有一个特有的 API,叫做 entry,它获取我们想要检查的键作为参数。entry 函数的返回值是一个枚举,Entry,它代表了可能存在也可能不存在的值。Entry 的 or_insert 方法在键对应的值存在时就返回这个值的可变引用,如果不存在则将参数作为新值插入并返回新值的可变引用。
根据旧值更新一个值
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);
