Rust编程语言-常用集合-Vector

Rust编程语言-常用集合-Vector

编码文章call10242025-04-25 11:12:5115A+A-

Vector存储列表

  • Vector写法是:Vec<T>
  • 由标准库提供,代码中可以直接使用,不用引入路径
  • 可以存储多个值
  • 只能存放相同类型的数据
  • 多个值在内存中连续存放

创建Vector

  • Vec::new函数
fn main() {
    let v: Vec<i32> = Vec::new();
}
  • 通常使用初始值来创建Vec<T>,这样就可以使用vec! 宏来创建Vector了
fn main() {
    let v = vec![1, 2, 3];
}

更新Vector

  • 向Vector添加元素,使用push方法
fn main() {
    // 使用 mut 申明是可变的,这样我们才能插入元素
    // 这里没有指定类型,因为接着就插入了值,rust能够推断类型
    // 如果没有插入数据,因为没有指定类型,编译通不过
    let mut v = Vec::new();

    v.push(5);
    v.push(6);
    v.push(7);
    v.push(8);
}

删除 Vector

  • 与任何其它struct一样,当Vector离开作用域后,vector会被清理掉,它里面的元素也会被清理掉

读取Vector的元素

  • 第一种方式:使用索引的方式读取,如果读取超出索引范围的数据会抛出异常
  • 第二种方式:使用get方法,超出范围的值不会异常,而是None,因为get返回的是Option
fn main() {
    let v = vec![1, 2, 3, 4, 5];

    let third: &i32 = &v[2];
    println!("The third element is {third}");

    let third: Option<&i32> = v.get(2);
    match third {
        Some(third) => println!("The third element is {third}"),
        None => println!("There is no third element."),
    }
}

vector所有权和借用规则

  • 不能在同一作用域内同时拥有某个值的可变和不可变引用
fn main() {
    let mut v = vec![1, 2, 3, 4, 5];
    // 产生一个不可变引用
    let first = &v[0];
    // 产生可变引用
    v.push(6);
    // 这里再使用不可变引用,就会出问题了,除非在可变引用之后不再使用first不可变引用
    println!("The first element is: {first}");
}

first引用的是第0个,而我们向vector末尾添加元素,为什么不可以呢?

因为vector在内存中是连续存放的,当我们再次向内存中添加元素,所在空间不够时,会对内存进行重新分配,找一块足够的空间。这样原先存放的地址就会被释放,这时 first 还是指向释放的空间,就有问题了。

遍历Vector中的值

  • for 循环
fn main() {
    let v = vec![100, 32, 57];
    for i in &v {
        println!("{i}");
    }
}

遍历修改vector的值:

fn main() {
    // 声明成可变
    let mut v = vec![100, 32, 57];
    // 引用也必须可变
    for i in &mut v {
        // *i 是对i解引用,从而可以获取到引用对应的值,因为i对应的是地址 *i才是值
        *i += 50;
    }
}
值就变成了 [150, 82, 107]

Vector + enum

因为vector只能存放相同元素值,这很不方便。好在enum的成员在rust中被认为是相同的枚举类型,所以当需要在 vector 中储存不同类型值时,我们可以定义并使用一个枚举!

  • enum的变体可以附加不同类型的数据
  • enum的变体定义在同一个enum类型下
fn main() {
    // excel 单元格存放类型
    enum SpreadsheetCell {
        Int(i32),
        Float(f64),
        Text(String),
    }

    let row = vec![
        SpreadsheetCell::Int(3),
        SpreadsheetCell::Text(String::from("blue")),
        SpreadsheetCell::Float(10.12),
    ];
}

Rust 在编译时就必须准确的知道 vector 中类型的原因在于它需要知道储存每个元素到底需要多少内存。第二个好处是可以准确的知道这个 vector 中允许什么类型。如果 Rust 允许 vector 存放任意类型,那么当对 vector 元素执行操作时一个或多个类型的值就有可能会造成错误。使用枚举外加 match 意味着 Rust 能在编译时就保证总是会处理所有可能的情况,正如第六章讲到的那样。

如果在编写程序时不能确切无遗地知道运行时会储存进 vector 的所有类型,枚举技术就行不通了。相反,你可以使用 trait 对象,后面会学到。

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4