08-常见集合
Vec、String 与 HashMap 的创建、访问、更新与所有权要点
精要笔记 · 基于 TRPL 简体中文 第8章
常见集合
集合数据在堆上,大小运行时可变。本章三种:Vec、String、HashMap。
使用 Vector 储存列表
Vec<T>:同类型、内存相邻、数量可变。
新建 vector
1
2
| let v: Vec<i32> = Vec::new();
let v = vec![1, 2, 3]; // 宏推断类型
|
更新 vector
1
2
3
| let mut v = Vec::new();
v.push(5);
v.push(6);
|
读取 vector 的元素
| 方式 | 越界行为 |
|---|
&v[i] | panic |
v.get(i) | 返回 Option<&T> |
- 同一作用域不能同时持有元素引用又对 vector push(可能重新分配,引用失效)。
遍历 vector 中的元素
1
2
| for i in &v { /* 不可变 */ }
for i in &mut v { *i += 50; } // 可变需解引用
|
使用枚举来储存多种类型
1
2
| enum SpreadsheetCell { Int(i32), Float(f64), Text(String) }
let row = vec![SpreadsheetCell::Int(3), ...];
|
- 运行时类型未知 → 用 trait 对象(第18章)。
丢弃 vector 时也会丢弃其所有元素
- vector 离开作用域,内部所有值一并 drop。
使用字符串储存 UTF-8 编码的文本
&str:字符串 slice,UTF-8 引用(含字面值)。String:可增长、可变、可拥有、UTF-8;本质是带额外语义的 Vec<u8>。
新建字符串
1
2
3
| let s = String::new();
let s = "initial".to_string();
let s = String::from("initial");
|
更新字符串
1
2
3
4
| s.push_str("bar"); // 追加 &str
s.push('l'); // 追加 char
let s3 = s1 + &s2; // s1 被 move;s2 用 &str
let s = format!("{}-{}-{}", t, u, v); // 不取得所有权
|
+ 调用 add(self, s: &str):self 被 move,第二参数为 &str(&String 可 deref coercion)。
索引字符串
String 不支持 s[i](字节索引 ≠ Unicode 标量/字形簇;且无法 O(1) 保证)。
内部表现
- UTF-8:拉丁字母常 1 字节/字符;西里尔、中文等可能多字节/字符。
- 三种视角:字节、标量值(
char)、字形簇(最像“字母”)。
字符串 slice
1
| let s = &hello[0..4]; // 字节范围;须在 char 边界,否则 panic
|
遍历字符串
1
2
| for c in "Зд".chars() { } // Unicode 标量
for b in "Зд".bytes() { } // 原始字节
|
使用 Hash Map 储存键值对
HashMap<K, V>:键→值映射;需 use std::collections::HashMap(不在 prelude)。
新建一个哈希 map
1
2
| let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
|
访问哈希 map 中的值
1
2
3
| let score = scores.get("Blue"); // Option<&V>
let v = scores.get("Blue").copied().unwrap_or(0);
for (k, v) in &scores { }
|
在哈希 map 中管理所有权
Copy 类型(如 i32)拷贝进 map。- 拥有权类型(如
String)move 进 map,原绑定失效。 - 存引用:引用所指值须比 map 活得久(生命周期,第10章)。
更新哈希 map
- 同键
insert → 覆盖旧值。 entry(key).or_insert(value):无键则插入,返回 &mut V(可用来计数)。
1
2
| let count = map.entry(word).or_insert(0);
*count += 1;
|
哈希函数
- 默认 SipHash(抗 DoS);可换
BuildHasher 实现(crates.io)。