《Rust编程入门》8.1 标准集合(Vec、HashMap、String等)

8.1 标准集合(Vec、HashMap、String 等) Rust 提供了一些强大的标准集合类型,用于存储和操作不同类型的数据。常见的标准集合包括 Vec、HashMap、String 等,这些集合是 Rust 标准库中的核心组成部分,能够高效地处理动态数据结构。下面,我们将逐一介绍这些常用的数据结构。

8.1 标准集合(Vec、HashMap、String 等)

Rust 提供了一些强大的标准集合类型,用于存储和操作不同类型的数据。常见的标准集合包括 VecHashMapString 等,这些集合是 Rust 标准库中的核心组成部分,能够高效地处理动态数据结构。下面,我们将逐一介绍这些常用的数据结构。

8.1.1 Vec<T>:动态数组

Vec(全称:vector)是 Rust 中最常用的集合类型之一。它是一个动态数组,可以存储任意类型的数据,并且在运行时能够根据需要自动调整大小。Vec 提供了丰富的 API,可以方便地对其进行插入、删除、访问等操作。

创建和初始化 Vec

fn main() {
    // 创建一个空的 Vec
    let mut v: Vec<i32> = Vec::new();

    // 向 Vec 中添加元素
    v.push(1);
    v.push(2);
    v.push(3);

    println!("{:?}", v);  // 输出: [1, 2, 3]
}
  • Vec::new() 创建了一个空的 Vec,我们可以通过 push 方法向其中添加元素。
  • 在 Rust 中,Vec 是类型安全的,我们在创建时需要指定它所存储的元素类型,如上例中的 i32

访问 Vec 中的元素

fn main() {
    let v = vec![1, 2, 3, 4, 5];

    // 访问第一个元素
    let first = v[0];
    println!("First element: {}", first);  // 输出: First element: 1

    // 使用 get 方法进行访问,避免下标越界
    match v.get(2) {
        Some(value) => println!("Third element: {}", value),  // 输出: Third element: 3
        None => println!("No such element"),
    }
}
  • v[0] 是直接通过下标访问元素的方式。如果访问一个不存在的元素(比如超出索引范围),会发生运行时 panic。
  • get 方法更安全,它返回一个 Option 类型,可以处理越界的情况,避免程序崩溃。

迭代 Vec 中的元素

fn main() {
    let v = vec![1, 2, 3, 4, 5];

    for val in &v {
        println!("{}", val);  // 输出: 1 2 3 4 5
    }
}
  • &v 表示对 Vec 的借用,迭代器会按引用访问元素,而不会消耗 Vec 中的数据。
  • 使用 for 循环遍历 Vec 中的元素是最常见的方式。

移除元素

fn main() {
    let mut v = vec![1, 2, 3, 4, 5];
    
    // 移除最后一个元素
    let last = v.pop();
    println!("Popped: {:?}", last);  // 输出: Popped: Some(5)
    
    // 移除并返回指定位置的元素
    let removed = v.remove(1);  // 移除索引为 1 的元素
    println!("Removed: {}", removed);  // 输出: Removed: 2
    
    println!("{:?}", v);  // 输出: [1, 3, 4]
}
  • pop 方法移除并返回 Vec 中的最后一个元素。
  • remove 方法移除指定位置的元素,并返回该元素。

8.1.2 HashMap<K, V>:哈希表

HashMap 是一种键值对存储结构,允许你根据键来存储、检索和修改数据。它是通过哈希函数来管理键的映射,因此适合用于查找效率较高的场景。与 Vec 不同,HashMap 的键必须是可哈希的类型(实现了 Hash 特征),值可以是任意类型。

创建和初始化 HashMap

use std::collections::HashMap;

fn main() {
    let mut scores = HashMap::new();
    
    // 向 HashMap 中插入键值对
    scores.insert("Alice", 50);
    scores.insert("Bob", 60);
    scores.insert("Charlie", 70);
    
    println!("{:?}", scores);  // 输出: {"Alice": 50, "Bob": 60, "Charlie": 70}
}
  • HashMap::new() 创建一个空的 HashMap,并通过 insert 方法插入键值对。

访问 HashMap 中的元素

use std::collections::HashMap;

fn main() {
    let mut scores = HashMap::new();
    scores.insert("Alice", 50);
    scores.insert("Bob", 60);
    
    // 使用 get 方法访问值
    match scores.get("Alice") {
        Some(&score) => println!("Alice's score: {}", score),  // 输出: Alice's score: 50
        None => println!("No score for Alice"),
    }
}
  • 使用 get 方法可以安全地访问 HashMap 中的元素,如果键不存在,返回 None

遍历 HashMap

use std::collections::HashMap;

fn main() {
    let mut scores = HashMap::new();
    scores.insert("Alice", 50);
    scores.insert("Bob", 60);
    
    for (key, value) in &scores {
        println!("{}: {}", key, value);
    }
}
  • for (key, value) in &scores 语法可以遍历 HashMap 中的所有键值对。

修改 HashMap 中的值

use std::collections::HashMap;

fn main() {
    let mut scores = HashMap::new();
    scores.insert("Alice", 50);
    
    // 修改已有键的值
    if let Some(score) = scores.get_mut("Alice") {
        *score += 10;
    }
    
    println!("{:?}", scores);  // 输出: {"Alice": 60}
}
  • get_mut 方法返回一个可变引用,我们可以修改 HashMap 中已有键的值。

8.1.3 String:可变字符串

String 是 Rust 中一个用于存储可变字符串的类型,它是堆分配的,可以动态扩展。与字符串字面量(&str)不同,String 是可以改变内容的。

创建和修改 String

fn main() {
    let mut s = String::from("Hello");

    // 向 String 中添加内容
    s.push_str(", World!");
    s.push('!');
    
    println!("{}", s);  // 输出: Hello, World!!
}
  • String::from 用于从一个字符串字面量创建 Stringpush_str 可以向字符串添加其他内容,push 向字符串添加单个字符。

访问 String 中的字符

fn main() {
    let s = String::from("Hello");

    for c in s.chars() {
        println!("{}", c);
    }
}
  • 使用 chars 方法可以遍历 String 中的字符(每个字符是一个 Unicode 标量值)。

字符串切片与借用

fn main() {
    let s = String::from("Hello, World!");
    let slice = &s[0..5];  // 获取字符串的切片

    println!("{}", slice);  // 输出: Hello
}
  • 字符串切片允许我们从 String 中借用一部分数据,而不需要复制内容。

8.1.4 小结

  • Vec<T> 是一个动态数组,支持灵活的元素插入、删除和访问操作,适用于存储可变大小的数据。
  • HashMap<K, V> 是一个哈希表,允许根据键快速查找、插入和删除值,适合用于键值对数据存储。
  • String 提供了一个堆分配的可变字符串类型,可以方便地处理和修改字符串数据。

这些标准集合类型使得 Rust 在处理常见数据结构时,既高效又安全。在下一节中,我们将深入探讨 Rust 的迭代器和迭代器适配器,使得集合的操作更加灵活和高效。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页