rust学习——用向量(vectors)存储值列表

向量使我们可以在单个数据结构中存储多个值,该结构将所有值彼此相邻放置在内存中。 向量只能存储相同类型的值。当我们具有项目列表时,例如文件中的文本行或购物车中项目的价格时,它们很有用。

新建一个vector

fn main() {
    let v: Vec = Vec::new();
    println!("{:?}", v)
}
D:\learn\cargo_learn>cargo run
   Compiling cargo_learn v0.1.0 (D:\learn\cargo_learn)
    Finished dev [unoptimized + debuginfo] target(s) in 1.06s
     Running `target\debug\cargo_learn.exe`
[]

可以看到其实vector就是一个数组,只不过有一个要求就是数组中的每一个元素必须具有相同的类型,下面创建一个真实的实例:

fn main() {
    let v = vec![1, 2, 3];
    println!("{:?}", v);
}
D:\learn\cargo_learn>cargo run
   Compiling cargo_learn v0.1.0 (D:\learn\cargo_learn)
    Finished dev [unoptimized + debuginfo] target(s) in 0.52s
     Running `target\debug\cargo_learn.exe`
[1, 2, 3]

如果不用相同类型的数据会怎样呢?

fn main() {
    let v = vec![1, 2.1, 3];
    println!("{:?}", v);
}

D:\learn\cargo_learn>cargo run
   Compiling cargo_learn v0.1.0 (D:\learn\cargo_learn)
error[E0308]: mismatched types
 --> src\main.rs:2:21
  |
2 |     let v = vec![1, 2.1, 3];
  |                     ^^^ expected integer, found floating-point number

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: could not compile `cargo_learn`.

To learn more, run the command again with --verbose.

更新一个向量
在rust中不管更新任何变量,其必须是可变的

fn main() {
    let mut v = Vec::new();

    v.push(5);
    v.push(6);
    v.push(7);
    v.push(8);
    println!("{:?}", v)
}
D:\learn\cargo_learn>cargo run
   Compiling cargo_learn v0.1.0 (D:\learn\cargo_learn)
    Finished dev [unoptimized + debuginfo] target(s) in 0.57s
     Running `target\debug\cargo_learn.exe`
[5, 6, 7, 8]
可以看出跟js中的数组没有任何区别,至少在使用push方法上~~

删除一个向量

与rust中的普通变量一样,向量也是一个变量,在超出其作用域之后会被自动清理,例如:

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

        // 在此可以用v做任何想做且能做的事情
    } // <- v超出范围并在此处释放
}

读取向量中的元素

有两种方式获取向量中的元素:使用索引和使用get方法:

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

    let third: &i32 = &v[2];
    println!("第三个元素是: {}", third);

    match v.get(2) {
        Some(third) => println!("第三个元素是: {}", third),
        None => println!("第三个元素不存在"),
    }
}

D:\learn\cargo_learn>cargo run
   Compiling cargo_learn v0.1.0 (D:\learn\cargo_learn)
    Finished dev [unoptimized + debuginfo] target(s) in 0.52s
     Running `target\debug\cargo_learn.exe`
第三个元素是: 3
第三个元素是: 3
直接使用索引值的话,如果索引值超出了向量的长度范围(0 ~ 长度-1),会导致编译或者运行出错,使用get方法可以安全的获取元素与捕获异常。

使用get方法可以简单一点,比如:

 let does_not_exist = v.get(100);

 println!("{:?}", does_not_exist);

此时,如果索引超出了向量可以被索引的范围的话会返回None

有意思的是如果稍微不注意仍旧会碰到所有权的现象:

fn main() {
    let mut v = vec![1, 2, 3, 4, 5];

    let first = &v[0];

    v.push(6);

    println!("The first element is: {}", first);
}

D:\learn\cargo_learn>cargo run
   Compiling cargo_learn v0.1.0 (D:\learn\cargo_learn)
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
 --> src\main.rs:6:5
  |
4 |     let first = &v[0];
  |                  - immutable borrow occurs here
5 | 
6 |     v.push(6);
  |     ^^^^^^^^^ mutable borrow occurs here
7 | 
8 |     println!("The first element is: {}", first);
  |                                          ----- immutable borrow later used here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.
error: could not compile `cargo_learn`.

To learn more, run the command again with --verbose.

遍历向量中的值

1、普通遍历,并打印出向量中的所有值

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

2、遍历并按照一定规则改变向量中的值

fn main() {
    let mut v = vec![100, 32, 57];
    for i in &mut v {
        *i += 50;
    }
}
要更改可变引用所引用的值,必须先使用解引用运算符(*)来获取i中的值,然后才能使用+ =运算符。

使用枚举存储多种类型
在rust中枚举的变体是在相同的枚举类型下定义的,因此当我们需要在向量中存储不同类型的元素时,我们可以定义和使用枚举!例如:

fn main() {
    #[derive(Debug)]
    enum SpreadsheetCell {
        Int(i32),
        Float(f64),
        Text(String),
    }

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

    println!("{:?}", row)
}

D:\learn\cargo_learn>cargo run
   Compiling cargo_learn v0.1.0 (D:\learn\cargo_learn)
    Finished dev [unoptimized + debuginfo] target(s) in 0.63s
     Running `target\debug\cargo_learn.exe`
[Int(3), Text("blue"), Float(10.12)]

也可以理解为使其可行的原因是:将枚举当做了一种类型存储在向量中

你可能感兴趣的:(rust)