Rust学习文档(四)

目录

[04 集合类型](#04 集合类型)

[4.1 Vector(动态数组)](#4.1 Vector(动态数组))

创建与基本操作

遍历

[所有权与 Vector](#所有权与 Vector)

常用方法速查

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

[Rust 字符串类型全景](#Rust 字符串类型全景)

创建字符串

更新字符串

索引字符串

[String 内部结构](#String 内部结构)

常用方法速查

[4.3 哈希 Map(HashMap)](#4.3 哈希 Map(HashMap))

创建与基本操作

访问值

[更新 HashMap](#更新 HashMap)

所有权

常用方法速查

[4.4 三大集合对比](#4.4 三大集合对比)

学习目标检验


04 集合类型

4.1 Vector(动态数组)

创建与基本操作

rust 复制代码
// 创建
let mut v: Vec<i32> = Vec::new();
let v = vec![1, 2, 3];         // 宏创建并初始化

// 添加元素
let mut v = Vec::new();
v.push(5);
v.push(6);

// 读取元素
let third = &v[2];              // 索引访问(越界会 panic)
let third = v.get(2);          // 返回 Option<&T>(安全访问)

match v.get(100) {
    Some(value) => println!("第100个是: {value}"),
    None => println!("没有第100个元素"),
}

遍历

rust 复制代码
let v = vec![100, 32, 57];

// 不可变遍历
for i in &v {
    println!("{i}");
}

// 可变遍历
let mut v = vec![100, 32, 57];
for i in &mut v {
    *i += 50;                   // 解引用后修改
}

所有权与 Vector

rust 复制代码
enum SpreadsheetCell {
    Int(i32),
    Float(f64),
    Text(String),
}

let row = vec![
    SpreadsheetCell::Int(3),
    SpreadsheetCell::Text(String::from("blue")),
    SpreadsheetCell::Float(10.12),
];
// Vec 存储 heterogeneous 数据:枚举是标准方案

// 切片
let slice = &v[0..2];           // &[i32] 类型
let slice = &v[..];             // 整个 vector 的切片

常用方法速查

|-------------------|-------------------------------------------|----------------------|
| 方法 | 签名 | 说明 |
| push | fn push(&mut self, value: T) | 末尾添加 |
| pop | fn pop(&mut self) -> Option<T> | 弹出末尾元素 |
| remove | fn remove(&mut self, index: usize) -> T | 按索引移除 |
| len | fn len(&self) -> usize | 长度 |
| is_empty | fn is_empty(&self) -> bool | 是否为空 |
| contains | fn contains(&self, x: &T) -> bool | 是否包含(需 T: PartialEq) |
| sort | fn sort(&mut self) | 排序(需 T: Ord) |
| dedup | fn dedup(&mut self) | 去除连续重复 |
| clear | fn clear(&mut self) | 清空 |
| with_capacity | fn with_capacity(cap: usize) -> Vec<T> | 预分配容量 |

4.2 字符串(String)

Rust 字符串类型全景

|---------------------|-----------------------------|-------------|
| 类型 | 说明 | 使用场景 |
| String | 堆上分配,可增长,UTF-8 编码 | 运行时动态字符串 |
| &str**(字符串切片)** | 栈上(ptr + len),指向某处 UTF-8 数据 | 函数参数、字符串字面量 |
| str | 切片类型(unsized),不能直接使用 | 类型系统底层 |
| Cow | 写时克隆 | 避免不必要的分配 |

创建字符串

rust 复制代码
let mut s = String::new();              // 空 String
let s = String::from("hello");          // 从 &str 创建
let s = "hello".to_string();            // 从 &str 创建(通过 Display trait)
let s = String::from("你好");           // UTF-8 支持
let s = format!("{}-{}", "hello", "world");  // format! 宏

更新字符串

rust 复制代码
let mut s = String::from("foo");

s.push_str("bar");          // 追加 &str
s.push('l');                // 追加单个 char

// 使用 + 运算符(注意所有权)
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2;         // s1 被移动,s2 被借用
                            // + 实际上调用了 fn add(self, &str) -> String

// format! 宏(不获取所有权)
let s = format!("{}-{}", s2, "!!!");  // s2 仍然有效

索引字符串

rust 复制代码
let s = String::from("hello");
// let h = s[0];           // 编译错误!String 不支持索引(因为 UTF-8)

let s = String::from("你好");
// let h = &s[0..1];       // 运行时 panic!'你' 占 3 字节
let h = &s[0..3];           // OK,"你"

// 正确遍历:chars(Unicode 标量值)或 bytes(原始字节)
for c in "नमस्ते".chars() {
    println!("{c}");         // 输出每个 Unicode 字符
}

for b in "नमस्ते".bytes() {
    println!("{b}");         // 输出每个 UTF-8 字节
}

String 内部结构

复制代码
String(栈上):
复制代码
┌──────────┬─────┬───────────┐
复制代码
│ ptr ────→│ len │ capacity  │
复制代码
└──────────┴─────┴───────────┘
复制代码
             5 bytes  5 bytes
复制代码
堆上数据(UTF-8 编码):
复制代码
┌───┬───┬───┬───┬───┐
复制代码
│ h │ e │ l │ l │ o │
复制代码
└───┴───┴───┴───┴───┘
复制代码
  0   1   2   3   4

常用方法速查

|------------------------------------------------------|---------------------------------|
| 方法 | 说明 |
| len() | 返回字节数(非字符数!) |
| is_empty() | 是否为空 |
| push_str() | 追加 &str |
| push() | 追加 char |
| trim()****/ trim_start()****/ trim_end() | 去除空白 |
| split_whitespace() | 按空白分割(返回迭代器) |
| split() | 按模式分割 |
| contains() | 是否包含子串 |
| replace() | 替换 |
| to_lowercase()****/ to_uppercase() | 大小写转换 |
| as_str() | 转为 &str |
| into_bytes() | 消费 String,返回 Vec<u8> |
| from_utf8() | 从 Vec<u8> 创建 Result<String> |

4.3 哈希 Map(HashMap)

创建与基本操作

rust 复制代码
use std::collections::HashMap;

// 创建
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);

// 用 zip + collect 创建
let teams = vec![String::from("Blue"), String::from("Yellow")];
let initial_scores = vec![10, 50];
let scores: HashMap<_, _> = teams.into_iter().zip(initial_scores.into_iter()).collect();

访问值

rust 复制代码
let team_name = String::from("Blue");
let score = scores.get(&team_name);    // 返回 Option<&V>

// 遍历
for (key, value) in &scores {
    println!("{}: {}", key, value);
}

更新 HashMap

rust 复制代码
// 1. 覆盖旧值
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Blue"), 25);  // 覆盖为 25

// 2. 仅当 key 不存在时插入
scores.entry(String::from("Blue")).or_insert(50);
// entry 返回 Entry 枚举,or_insert 在 Vacant 时插入

// 3. 基于旧值更新
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;   // 解引用修改
}
// {"world": 2, "hello": 1, "wonderful": 1}

所有权

rust 复制代码
// key 和 value 被移动到 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 已失效

// 使用引用(需要生命周期)
fn hash_map_example() {
    let mut map: HashMap<&str, &str> = HashMap::new();
    map.insert("key", "value");
}

常用方法速查

|------------------------------|--------------------------|
| 方法 | 说明 |
| insert(k, v) | 插入键值对(返回 Option<V>:旧值) |
| get(&k) | 获取值,返回 Option<&V> |
| remove(&k) | 删除,返回 Option<V> |
| contains_key(&k) | 是否包含 key |
| len() | 键值对数量 |
| is_empty() | 是否为空 |
| entry(k) | 获取 Entry(用于条件插入) |
| keys()****/ values() | 遍历所有 key / value |
| iter() | 遍历 (&K, &V) 引用 |
| clear() | 清空 |
| with_capacity(n) | 预分配容量 |

4.4 三大集合对比

|------------------|-------------------------|----------------------------|-----------------------------|
| 特性 | Vec\<T\> | String | HashMap\<K, V\> |
| 内部表示 | 连续内存(堆) | UTF-8 字节序列(堆) | 哈希桶(堆) |
| 增长策略 | 自动扩容(2x) | 自动扩容 | 自动扩容 |
| 索引 | O(1) | O(1) 按字节(不安全) | N/A |
| 查找 | O(n) 线性 / O(log n) 排序后 | 子串查找 O(n) | O(1) 平均 |
| 迭代 | 有序 | 有序(字节) | 无序(不保证遍历顺序) |
| Clone 花费 | O(n) | O(n) | O(n) |
| 预分配 | Vec::with_capacity(n) | String::with_capacity(n) | HashMap::with_capacity(n) |

学习目标检验

  • 能使用 vec! 宏创建 Vector,并 push/pop 遍历
  • 理解 String vs &str 的区别和使用场景
  • 知道为什么不能直接索引 String,理解 UTF-8
  • 能使用 HashMap::new()insertgetentry().or_insert()
  • 理解 HashMap 无序的特性
  • 知道何时预分配容量以提高性能
相关推荐
~kiss~2 小时前
大模型中的强化学习算法和对齐算法的区别
学习
CoderYanger2 小时前
A.每日一题:1979. 找出数组的最大公约数
java·程序人生·算法·leetcode·面试·职场和发展·学习方法
MartinYeung52 小时前
[论文学习]InjecAgent:工具集成大语言模型智能体的间接提示注入基准测试
网络·学习·语言模型
yaoxin5211232 小时前
476. Java 反射 - 调用方法
java·开发语言
回家路上绕了弯2 小时前
Java双数据源实战全指南:Spring Boot多数据源配置、原理与踩坑避坑
后端
神奇小汤圆2 小时前
Redis主从切换后,旧主恢复竟触发全量同步?——我猜错了,原因比想象中更严谨
后端
JoyT2 小时前
滚动MAD与孤立森林在时序异常检测中的协同应用
后端
记忆着2 小时前
标准库更多介绍
rust
程序员cxuan2 小时前
白嫖 Claude Max 20x 漏洞完整事件始末
人工智能·后端·程序员
labixiong2 小时前
React Compiler 用 Rust 重写了,编译提速 10 倍——手写 useMemo 的日子到头了
react.js·rust