vector,类型 Vec<T>,允许在一个单独的数据结构中储存多于一个的值,在内存中彼此相邻地排列所有的值。

新建 vector

  1. let v: Vec<i32> = Vec::new();

为了方便,Rust 提供了vec!宏,这个宏会根据提供的值来创建新 vector。

  1. let v = vec![1, 2, 3];

更新 vector

  1. let mut v = Vec::new();
  2. v.push(5);
  3. v.push(6);
  4. v.push(7);
  5. v.push(8);

丢弃 vector 时也会 丢弃其所有元素

  1. {
  2. let v = vec![1, 2, 3, 4];
  3. // 处理变量 v
  4. } // <- 这里 v 离开作用域并被丢弃

读取 vector 的元素

  1. let v = vec![1, 2, 3, 4, 5];
  2. let third: &i32 = &v[2];
  3. println!("The third element is {}", third);
  4. match v.get(2) {
  5. Some(third) => println!("The third element is {}", third),
  6. None => println!("There is no third element."),
  7. }

使用 get 方法以索引作为参数返回一个 Option<&T>,推荐用 get 方法,因为当 &[] 使用的索引超过 vector 上限,程序会 panic。
当我们获取了 vector 的第一个元素的不可变引用并尝试在 vector 末尾增加一个元素的时候,如果尝试在函数的后面引用这个元素是行不通的:

  1. fn main() {
  2. let mut v = vec![1, 2, 3, 4, 5];
  3. let first = &v[0];
  4. v.push(6);
  5. println!("The first element is: {}", first);
  6. }

会编译出现错误

  1. $ cargo run
  2. Compiling collections v0.1.0 (file:///projects/collections)
  3. error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
  4. --> src/main.rs:6:5
  5. |
  6. 4 | let first = &v[0];
  7. | - immutable borrow occurs here
  8. 5 |
  9. 6 | v.push(6);
  10. | ^^^^^^^^^ mutable borrow occurs here
  11. 7 |
  12. 8 | println!("The first element is: {}", first);
  13. | ----- immutable borrow later used here
  14. For more information about this error, try `rustc --explain E0502`.
  15. error: could not compile `collections` due to previous error

为什么第一个元素的引用会关心 vector 结尾的变化?不能这么做的原因是由于 vector 的工作方式:在 vector 的结尾增加新元素时,在没有足够空间将所有所有元素依次相邻存放的情况下,可能会要求分配新内存并将老的元素拷贝到新的空间中。这时,第一个元素的引用就指向了被释放的内存。借用规则阻止程序陷入这种状况。

遍历 vector 中的元素

  1. let v = vec![100, 32, 57];
  2. for i in &v {
  3. println!("{}", i);
  4. }

遍历时可以改变

  1. let mut v = vec![100, 32, 57];
  2. for i in &mut v {
  3. *i += 50;
  4. }

使用枚举来储存多种类型

  1. enum SpreadsheetCell {
  2. Int(i32),
  3. Float(f64),
  4. Text(String),
  5. }
  6. let row = vec![
  7. SpreadsheetCell::Int(3),
  8. SpreadsheetCell::Text(String::from("blue")),
  9. SpreadsheetCell::Float(10.12),
  10. ];

Rust 在编译时就必须准确的知道 vector 中类型的原因在于它需要知道储存每个元素到底需要多少内存。第二个好处是可以准确的知道这个 vector 中允许什么类型。如果 Rust 允许 vector 存放任意类型,那么当对 vector 元素执行操作时一个或多个类型的值就有可能会造成错误。