Rust - 集合
现代 Rust:常用集合
Section titled “现代 Rust:常用集合”Rust 的标准库(std::collections)提供了一套强大、高效且安全的集合类型,用于管理数据组。我们将探讨三个最核心的集合:Vec<T>(向量)、HashMap<K, V>(哈希映射)和 HashSet<T>(哈希集合)。
Vector:可变大小的列表
Section titled “Vector:可变大小的列表”Vec<T>(发音为“vector”,即向量)是一个可增长的、同类型 T 值的列表,它们在内存中连续存储。它是 Rust 中使用最广泛的数据结构之一。
- 同质: 所有元素必须是相同类型。
- 堆分配: 数据存储在堆上,允许其在运行时增长或缩小。
- 有序: 元素保持特定顺序,并通过从 0 开始的索引访问。
创建和操作向量
Section titled “创建和操作向量”fn main() { // 创建一个空向量并添加元素 let mut numbers: Vec<i32> = Vec::new(); numbers.push(10); numbers.push(20); numbers.push(30);
// 使用 vec! 宏创建带有初始值的向量 let mut fruits = vec!["Apple", "Banana", "Cherry"]; println!("Initial fruits: {:?}", fruits);
// 访问元素 // 使用 .get() 更安全,因为它返回 Option<&T> match fruits.get(1) { Some(fruit) => println!("The second fruit is: {}", fruit), None => println!("There is no second fruit."), }
// 如果索引超出范围,直接索引将导致 panic let first_fruit = &fruits[0]; println!("The first fruit is: {}", first_fruit);
// 迭代和修改 for fruit in &mut fruits { *fruit = "Juicy Fruit"; // 通过可变引用修改每个元素 } println!("Modified fruits: {:?}", fruits);}常用 Vec<T> 方法
Section titled “常用 Vec<T> 方法”| 方法 | 描述 |
|---|---|
Vec::new() | 创建一个新的空向量。 |
vec![...] | 一个方便的宏,用于创建带有初始元素的向量。 |
push(value) | 将一个元素添加到向量的末尾。 |
pop() | 移除并返回最后一个元素,以 Option<T> 形式。 |
len() | 返回向量中的元素数量。 |
get(index) | 返回 index 处元素的 Option<&T>。安全。 |
[index] | 返回 index 处元素的引用。如果超出边界则会导致 panic。 |
HashMap:键值存储
Section titled “HashMap:键值存储”一个 HashMap<K, V> 存储了类型 K 的键到类型 V 的值的映射。它使用哈希函数(hashing function)来确定如何存储和检索数据,使得查找、插入和删除操作在平均情况下极快。键必须是唯一的。
创建和使用 HashMap
Section titled “创建和使用 HashMap”use std::collections::HashMap;
fn main() { // 创建一个新的 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).copied().unwrap_or(0); println!("The score for Blue team is: {}", score);
// 遍历键值对 for (key, value) in &scores { println!("{}: {}", key, value); }}最佳实践:entry API
Section titled “最佳实践:entry API”entry API 是处理复杂逻辑的惯用方式,例如仅在键不存在时插入值,或更新现有值。
use std::collections::HashMap;
fn main() { let text = "hello world wonderful world"; let mut map = HashMap::new();
for word in text.split_whitespace() { // .entry() 返回一个表示潜在条目的枚举(Enum) // .or_insert(0) 获取值,如果不存在则插入 0 let count = map.entry(word).or_insert(0); *count += 1; // 递增计数 }
println!("Word counts: {:?}", map);}HashSet:唯一值的集合
Section titled “HashSet:唯一值的集合”一个 HashSet<T> 是一个集合,其中每个元素都是唯一的。它作为 HashMap<T, ()> 的一个包装器实现,并且在检查集合中是否存在某个值时速度极快。
创建和使用 HashSet
Section titled “创建和使用 HashSet”use std::collections::HashSet;
fn main() { let mut visited_cities = HashSet::new();
// insert() 如果值是新插入的,则返回 true assert!(visited_cities.insert("Tokyo")); assert!(visited_cities.insert("London")); // 插入重复值返回 false assert!(!visited_cities.insert("Tokyo"));
println!("Visited cities: {:?}", visited_cities);
// 检查是否存在 if visited_cities.contains("London") { println!("We have been to London!"); }}HashSet 还支持强大的数学集合操作。
use std::collections::HashSet;
fn main() { let set1: HashSet<_> = [1, 2, 3].iter().cloned().collect(); let set2: HashSet<_> = [2, 3, 4].iter().cloned().collect();
// 并集:任一集合中的元素 println!("Union: {:?}", set1.union(&set2).collect::<Vec<_>>());
// 交集:两个集合中都存在的元素 println!("Intersection: {:?}", set1.intersection(&set2).collect::<Vec<_>>());
// 差集:在 set1 中但不在 set2 中的元素 println!("Difference: {:?}", set1.difference(&set2).collect::<Vec<_>>());}选择正确的集合
Section titled “选择正确的集合”- 当你需要一个有序的元素序列时,使用
Vec<T>。 - 当你需要将值与唯一键关联以进行快速查找时,使用
HashMap<K, V>。 - 当你只需要存储唯一值并快速检查它们是否存在时,使用
HashSet<T>。