使用 Vector 存储多个值

  • Vec,叫做 vector
  • 由标准库提供
  • 可存储多个值
  • 只能存储相同类型的数据
  • 值在内存中连续存放

    创建 Vector

  • Vec::new 函数

    1. fn main() {
    2. let v: Vec<i32> = Vec::new();
    3. }

    Vec::new() 创建的是空的,里面没有元素,所以 Rust 无法推断出里面的元素类型,所以这里需要指明类型。

  • 使用初始值创建 Vec,使用 vec! 宏

    1. fn main() {
    2. let v = vec![1, 2, 3];
    3. }

    更新 Vector

  • 向 Vector 添加元素,使用 push 方法

    1. fn main() {
    2. let mut v = Vec::new();
    3. v.push(1);
    4. }

    删除 Vector

  • 与任何其他 struct 一样,当 Vector 离开作用域后

    • 它就被清理掉了
    • 它所有的元素也被清理掉了
      1. fn main() { // v 在这里无效, 它尚未声明
      2. let v = vec![1, 2, 3]; // 从此处起,v 是有效的
      3. // 使用 v
      4. } // 此作用域已结束,v 不再有效

      读取 Vector 元素

  • 两种方式可以引用 Vector 里的值

    • 索引
    • get 方法

      1. fn main() {
      2. let v = vec![1, 2, 3, 4, 5];
      3. let third: &i32 = &v[2]; // 使用索引的方式访问第三个元素
      4. println!("The third element is {}", third);
      5. match v.get(2) { // 使用 get 方法,返回的是 Option 枚举
      6. Some(third) => println!("The third element is {}", third),
      7. None => println!("There is no third element"),
      8. }
      9. }

      索引 和 get 处理访问越界

  • 索引:painc

  • get:返回 None

使用索引的方式,如果索引超出了 Vector 范围,比如

  1. fn main() {
  2. let v = vec![1, 2, 3, 4, 5];
  3. let third: &i32 = &v[100]; // 使用索引的方式访问第三个元素
  4. println!("The third element is {}", third);
  5. match v.get(100) { // 使用 get 方法,返回的是 Option 枚举
  6. Some(third) => println!("The third element is {}", third),
  7. None => println!("There is no third element"),
  8. }
  9. }

程序会报错

  1. thread 'main' panicked at 'index out of bounds:
  2. the len is 5 but the index is 100', src/main.rs:3:24
  3. note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

但是使用 get 方法,会返回 None,以上是这两种方式对非法访问的区别。

所有权和借用规则

  • 不能在同一作用域内同时拥有可变和不可变引用

    1. fn main() {
    2. let v = vec![1, 2, 3, 4, 5];
    3. let first = &v[0]; // 对 v 的不可变的借用
    4. v.push(6); // 对 v 进行修改,发生了可变的借用
    5. println!("The first element is {}", first); // 不可变借用
    6. }

    这作用域内,同时对 v 的可变借用和不可变借用,第 4 行会报错,显示

    1. cannot borrow `v` as mutable because it is also borrowed as immutable
    2. --> src/main.rs:4:5

    向 Vector 添加元素的过程中,可能之前分配的连续地址不够,需要内存的重新分配,之前的内存会被释放,
    如果被释放了之后,规则允许的话,first 仍然会指向释放之前的地址,这样会出问题。
    借用规则防止这样的现象发生。

    遍历 Vector 中的值

  • for 循环

    1. fn main() {
    2. let v = vec![1, 2, 3, 4, 5];
    3. for i in &v { // 针对 v 里面的每个值获得不可变的引用
    4. println!("{}", i);
    5. }
    6. }

    使用可变的引用。轮流修改里面的值

    1. fn main() {
    2. let mut v = vec![1, 2, 3, 4, 5];
    3. for i in &mut v {
    4. *i += 50; // 解引用再加上 50
    5. }
    6. for i in &v {
    7. println!("{}", i);
    8. }
    9. }

    使用 enum 来存储多种类型数据

    在 Vector 里只能存放相同类型的数据,但有时候需要存储不同类型的数据。

  • enum 的变天可以附加不同类型的数据

  • enum 的变体定义再同一个 enum 类型下 ```rust enum SpreadsheetCell { Int(i32), Float(f64), Text(String), }

fn main() { let row = vec![ SpreadsheetCell::Int(3), SpreadsheetCell::Text(String::from(“blue”)), SpreadsheetCell::Float(10.12), ]; } ``` 通过使用可附加数据的枚举类型,就可以在 Vector 里存放不同类型的数据。