【Rust】常见集合

目录

思维导图

一、Rust常用集合

[1. Rust标准库中的集合概述](#1. Rust标准库中的集合概述)

[2. 常用集合类型](#2. 常用集合类型)

[2.1 向量(Vector)](#2.1 向量(Vector))

[2.2 字符串(String)](#2.2 字符串(String))

[2.3 哈希映射(Hash Map)](#2.3 哈希映射(Hash Map))

二、向量(Vec)

[1. 向量的概述](#1. 向量的概述)

[2. 创建向量](#2. 创建向量)

[3. 添加元素](#3. 添加元素)

[4. 访问元素](#4. 访问元素)

[5. 修改元素](#5. 修改元素)

[6. 遍历向量](#6. 遍历向量)

[7. 使用枚举存储多种类型](#7. 使用枚举存储多种类型)

8.向量的生命周期

三、字符串(String)

1.字符串的概述

2.字符串的创建

3.字符串的更新

4.字符串的连接

5.字符串的访问

四、哈希映射(HashMap)

[1. 哈希映射的概述](#1. 哈希映射的概述)

[2. 创建哈希映射](#2. 创建哈希映射)

[3. 插入哈希映射值](#3. 插入哈希映射值)

[4. 访问哈希映射中的值](#4. 访问哈希映射中的值)

[5. 遍历哈希映射](#5. 遍历哈希映射)

[6. 哈希映射的所有权](#6. 哈希映射的所有权)

[7. 更新哈希映射](#7. 更新哈希映射)

[8. 哈希函数](#8. 哈希函数)


思维导图

一、Rust常用集合

1. Rust标准库中的集合概述

Rust的标准库包含了一些非常有用的数据结构,统称为集合(Collections)。与其他数据类型不同,集合可以存储多个值。集合的数据存储在堆上,因此其大小可以在程序运行时动态变化,而不必在编译时确定。

2. 常用集合类型

在Rust中,常用的集合类型主要包括以下三种:

2.1 向量(Vector)
  • 定义:向量是一种可以存储可变数量的值的集合。
  • 特点:向量的元素在内存中是连续存储的,可以根据需要动态扩展或缩减。
  • 使用场景:适合需要频繁插入、删除元素的场合,能够高效地处理动态数据。
2.2 字符串(String)
  • 定义:字符串是字符的集合。
  • 特点 :Rust中的String类型支持动态大小,可以根据需要进行扩展。
  • 使用场景:适用于需要处理文本数据的场合,如用户输入、文件读取等。
2.3 哈希映射(Hash Map)
  • 定义:哈希映射是一种将特定键与值关联的数据结构,属于更通用的数据结构"映射"的一种实现。
  • 特点:允许通过键快速访问对应的值,适合存储键值对数据。
  • 使用场景:常用于需要快速查找、插入和删除的场合,如缓存实现、统计数据等。

二、向量(Vec)

1. 向量的概述

**向量(Vec<T>)**是一种动态数组,可以存储多个相同类型的值。它在内存中是连续存储的,支持高效的随机访问和动态扩展。

2. 创建向量

1)空向量的创建 :使用Vec::new()函数创建一个空向量。例如:

rust 复制代码
fn main() {
    let v: Vec<i32> = Vec::new();[3]
    //这里需要类型注释,因为未插入任何值,Rust无法推断元素类型。
}

2) 带初始值的向量 :使用vec!宏创建带初始值的向量。例如:

rust 复制代码
fn main() {
    let v = vec![1, 2, 3];
    //Rust可以根据提供的初始值推断类型为Vec<i32>,因此类型注释不再必要。
}

3. 添加元素

添加元素 :使用push方法向向量中添加元素,必须将向量声明为可变(mutable):

rust 复制代码
fn main() {
    let mut v = Vec::new();
    v.push(5);
    v.push(6);
}

4. 访问元素

访问元素 :可以通过索引或get方法访问向量中的元素。值得注意的是,使用get方法时,如果索引超出范围,返回None,而使用索引直接访问则会导致程序崩溃。例如:

rust 复制代码
let third: &i32 = &v[2];
let third: Option<&i32> = v.get(2);

5. 修改元素

1)通过索引直接修改: 通过索引可以直接访问并修改向量中的元素。需要注意的是,向量必须是可变的(mut),并且索引必须在有效范围内。例如:

rust 复制代码
fn main() {
    let mut v = vec![1, 2, 3, 4];

    // 修改索引为 2 的元素
    v[2] = 100;

    println!("{:?}", v); // 输出: [1, 2, 100, 4]
}

2)通过get_mut方法修改: get_mut 方法返回一个 Option<&mut T>,允许安全地修改元素。如果索引有效,则返回可变引用;如果索引无效,则返回 None。例如:

rust 复制代码
fn main() {
    let mut v = vec![1, 2, 3, 4];

    // 获取索引为 2 的可变引用
    if let Some(elem) = v.get_mut(2) {
        *elem = 100; // 修改元素
    }

    println!("{:?}", v); // 输出: [1, 2, 100, 4]
}

6. 遍历向量

1)不可变遍历 :使用for循环遍历向量中的每个元素:

rust 复制代码
for i in &v {
    println!("{i}");
}

2)可变遍历:可以通过可变引用遍历并修改每个元素:

rust 复制代码
for i in &mut v {
    *i += 50;
}

7. 使用枚举存储多种类型

由于向量只能存储相同类型的值,可以使用枚举来存储不同类型的值。例如:

rust 复制代码
enum SpreadsheetCell {
    Int(i32),
    Float(f64),
    Text(String),
}
let row = vec![
    SpreadsheetCell::Int(3),
    SpreadsheetCell::Text(String::from("blue")),
    SpreadsheetCell::Float(10.12),
];

8.向量的生命周期

向量在超出作用域时会自动释放其内存,所有元素也会随之释放。例如:

rust 复制代码
{
    let v = vec![1, 2, 3, 4];
} // v 超出作用域并被释放

三、字符串(String)

1.字符串的概述

字符串(String 是 UTF-8 编码的字符集合,支持动态扩展。Rust 的字符串类型包括 String 和字符串切片 &str。

2.字符串的创建

通过String::new()创建一个新的空字符串,或使用to_string()和String::from()方法从字符串字面量创建字符串。示例代码如下:

rust 复制代码
fn main() {
    let mut s = String::new();
    let data = "initial contents";
    let s1 = data.to_string();
    let s2 = String::from("initial contents");
}

3.字符串的更新

String可以通过push_str方法追加字符串切片,或使用push方法添加单个字符。示例代码如下:

rust 复制代码
fn main() {
    let mut s = String::from("foo");
    s.push_str("bar");
    s.push('!');    //foobar!
}

4.字符串的连接

可以使用 +操作符或format!宏来连接字符串。使用 +操作符时,左侧字符串会被移动,示例代码如下:

rust 复制代码
fn main() {
    let s1 = String::from("Hello, ");[7][8]
    let s2 = String::from("world!");
    let s3 = s1 + &s2; // s1被移动,s2仍然有效
}

5.字符串的访问

Rust不支持直接通过索引访问字符串中的字符,需使用chars()方法或bytes()方法进行迭代。例如:

rust 复制代码
fn main() {
    let hello = "Здравствуйте";[7]
    for c in hello.chars() {
        println!("{c}");
    }
}

四、哈希映射(HashMap)

1. 哈希映射的概述

**哈希映射(HashMap<K, V>)**是一种键值对集合,通过哈希函数将键映射到值。它允许通过键快速查找、插入和删除值。

2. 创建哈希映射

可以使用HashMap::new()方法创建一个空的哈希映射。示例代码:

rust 复制代码
fn main() {
    use std::collections::HashMap;
    let mut scores = HashMap::new();
}

3. 插入哈希映射值

可以使用insert方法添加元素。示例代码:

rust 复制代码
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);

4. 访问哈希映射中的值

可以使用get方法通过键访问对应的值,返回类型为Option<&V>,如果键不存在,则返回None。示例代码:

rust 复制代码
let score = scores.get(&team_name).copied().unwrap_or(0);

ps: 此程序通过调用 copied 来获取一个 Option<i32> 而不是 Option<&i32> 来处理 Option ,然后如果 scores 没有该键的条目,则调用 unwrap_or 将 score 设置为零。

5. 遍历哈希映射

可以使用for循环遍历哈希映射中的每个键值对。示例代码:

rust 复制代码
for (key, value) in &scores {
    println!("{key}: {value}");
}

6. 哈希映射的所有权

对于实现了Copy特性的类型(如i32),值会被复制到哈希映射中;对于拥有所有权的类型(如String),值会被移动到哈希映射中。示例代码:

rust 复制代码
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和field_value在插入后失效
}

7. 更新哈希映射

1)覆盖值:插入同一键的新值会替换旧值。示例代码:

rust 复制代码
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Blue"), 25);
//{"Blue": 25}

2)仅在键不存在时插入 :使用entry方法检查键是否存在,若不存在则插入新值。示例代码:

rust 复制代码
scores.entry(String::from("Yellow")).or_insert(50);

ps-1: entry 方法的返回值是一个名为 Entry的枚举,它表示一个可能存在也可能不存在的值。

ps-2: Entry 上的 or_insert 方法被定义为:如果对应的 Entry 键存在,则返回该值的可变引用;如果不存在,则将参数插入作为该键的新值,并返回新值的可变引用。

8. 哈希函数

默认情况下,HashMap使用名为SipHash的哈希函数,具有防止拒绝服务(DoS)攻击的能力。虽然其性能可能不如其他哈希算法,但在安全性和性能之间的权衡是值得的。

tips:

  • 向量 :常用操作包括创建(Vec::new()vec![])、添加(push)、访问(索引、get)、修改(索引、get_mut)和遍历(for循环)。

  • 字符串 :常用操作包括创建(String::new()to_string())、更新(push_strpush)、连接(+format!)和遍历(chars()bytes())。

  • 哈希映射 :常用操作包括创建(HashMap::new())、插入(insert)、访问(get)、遍历(for循环)和更新(entryor_insert)。

相关推荐
Panda-gallery19 分钟前
【Rust】错误处理机制
开发语言·后端·rust
Panda-gallery23 分钟前
【Rust】结构体的方法语法
开发语言·后端·rust
从善若水27 分钟前
【Rust学习笔记】Rust 的所有权介绍
笔记·学习·rust
get_money_28 分钟前
贪心算法汇总
java·开发语言·数据结构·算法·leetcode·贪心算法
ByteBlossom66629 分钟前
Perl语言的语法
开发语言·后端·golang
摇光931 小时前
js观察者模式
开发语言·javascript·观察者模式
誓约酱1 小时前
Linux下ext2文件系统
android·linux·c语言·数据库·c++·后端·ubuntu
山茶花开时。1 小时前
[SAP ABAP] 使用LOOP AT...ASSIGNING FIELD-SYMBOL 直接更新内表数据
开发语言·sap·abap
java熊猫2 小时前
CSS语言的网络编程
开发语言·后端·golang
生活很暖很治愈2 小时前
C语言之旅5--分支与循环【2】
c语言·开发语言