Skip to main content

C8 常用集合类型

https://doc.rust-lang.org/book/ch08-00-common-collections.html

Rust 标准库提供许多常用集合类型, 这些集合通常都存储在堆上. 我们将主要看:

  • Vector: 动态数组, 用于保存可变数量的值, 物理存储连续(会分配连续存储空间).
  • String: 字符串, 为字符的集合.
  • HashMap: 字典, 存放键值对.

Vector 相关操作

  • 创建: 使用 newvec! 宏.

  • 插入: 使用 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 攻击.