C8 常用集合类型
https://doc.rust-lang.org/book/ch08-00-common-collections.html
Rust 标准库提供许多常用集合类型, 这些集合通常都存储在堆上. 我们将主要看:
Vector
: 动态数组, 用于保存可变数量的值, 物理存储连续(会分配连续存储空间).String
: 字符串, 为字符的集合.HashMap
: 字典, 存放键值对.
Vector 相关操作
-
创建: 使用
new
或vec!
宏. -
插入: 使用
push
-
读取:
- 下标:
let third = &v[2]
get
方法:v.get(2)
, 结果为Option<&T>
- 下标:
-
遍历:
- 不可变:
let v = vec![100, 32, 57];
for i in &v {
// 获取到元素的不可变引用
} - 可变:
let mut v = vec![100, 32, 57];
for i in &mut v {
*i += 50; // 获取到元素的可变引用后解引用并修改
}
- 不可变:
-
技巧: 可以通过 enum 达到存放不同类型值的目的
enum SpreadsheetCell {
Int(i32),
Float(f64),
Text(String),
}
let row = vec![
SpreadsheetCell::Int(3),
SpreadsheetCell::Text(String::from("blue")),
SpreadsheetCell::Float(10.12),
];
String 保存 UTF-8 编码的字符串
String
是 Rust 标准库提供的类型, 而 Core 中只有 str
类型用于表示字符串常量.
- 创建:
new
,from
,to_string
(实现了Display
trait 的类型上),format!
宏等 - 追加:
push_str
(追加字符串),push
(追加字符),+
操作符(追加字符串),add
(和+
同理)
关于字符串为什么不支持下标访问: 由于下标表示的是一个字节(String
实际是 Vec<u8>
的一个包裹), 因此在 UTF-8(4字节表示一个字符)场景下可能取得的并非想要的字符!
但 Rust 提供对字符串的切片支持(通过下标范围), 但同样存在下标访问问题, 因此需要格外小心.
HashMap 字典
键值对存放时使用, 它通过一个哈希函数计算 key 对应的值在内存中的 存放位置.
- 创建:
new
- 插入:
insert
- 读取:
get
- 遍历:
for-in
循环 - 覆盖之前的值: 使用相同 Key 即可覆盖.
- "不存在则插入":
hsmap.entry(key).or_insert(value);
关于 HashMap 值的所有权规则:
- Copy 类型: 值被复制到 HashMap.
- 引用类型: 值不会被 move 到 HashMap, 但需要保证被加入的值生命期至少应和 HashMap 相同.
- 其他: 值被 move 到 HashMap.
关于 HashMap 使用的哈希函数:
- 默认情况下使用
SipHash
, 但速度可能不是最快的哈希函数, 它可以有效防御针对哈希表的 DoS 攻击.