One - One Code All

Blog Content

Rust中的集合类型之vectors

Rust   2017-04-22 08:09:59

Vec,也称为vector。它允许我们在一个单独的数据结构中存储一系列相同类型的值,它们在内存中彼此相邻的排列所有的值。


Vector VS 数组

不同点

  • vector是存储在堆上,数组存储在栈上

  • vector的长度是动态增长的,数组一旦定义,其长度就不能再次更改了

  • vector是标准库中用泛型实现的,数组是rust语言的原生内建类型

相同点:

  • 存储多个相同类型的值,它们在内存中彼此相邻

  • OS分配完内存之后默认都会标记这片内存只读不写[值不可变],如果想要修改元素值[内存可读可写],必须使用mut

  • 都只能在{}内部使用,不能再函数外面声明

  • 如果不覆盖的话,作用域均为从声明开始到下一个}结束。一旦离开作用域,它们的值和变量名均会被销毁

  • 在使用for in循环时,如果想要修改vector/array的元素,必须使用*解引用取出元素值才能修改


Vector

初始化

vector有两种初始化方法:使用Vec::new();函数或者使用Vec!宏

fn main() {
   //1:调用 Vec::new函数新建一个空的 vector 来储存 i32 类型的值
   let mut v:Vec<i32> = Vec::new();
   v.push(5);
   println!("{:?}",v);
   /*
   {} 需要被显示的类型实现 Display Trait
   {:?} 需要被显示的类型实现 Debug Trait
   */

   //2: vec!宏使用初始值来创建一个 Vec
   let v = vec![1, 2, 3];// v 离开作用域并被丢弃, 然后新建一个vector名字也叫做v
   println!("{:?}", v)

   let v = vec![0;10];
   println!("{:?}", v)  //[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
   println!("{:?}", v[0])   //可以使用索引访问vector中的值
}   // v 离开作用域并被丢弃


引用元素:&v[index] 对比 v.get(index)

1、&v[index]返回一个引用, v.get(index)方法返回一个 Option<&T>。

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

   let third:&i32 = &v[2];
   let gthird:Option<&i32> = v.get(2);
   println!("{}, {:?}", third, gthird);
}

2、如果越界访问的话,&v[index]会panic,v.get(index)会返回None,所以如果要引用vector的元素,建议使用v.get(index)

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

  // let third:&i32 = &v[100]; //thread 'main' panicked at 'index out of bounds: the len is 5 but the index is 100'
   let gthird:Option<&i32> = v.get(100);
   println!("{:?}", gthird);
}

循环修改元素

最好使用引用来循环遍历元素。引用获取值得使用权而不是控制权

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

   for i in &mut v{
       *i  += 100; //为了修改可变引用所指向的值,在使用 += 运算符之前必须使用解引用运算符(*)获取 i 中的值
   }

   for i in &v{
       println!("{}", i)
   }

   let mut arr = [1, 2, 3];
   for i in &mut arr{
       *i += 100;
   }
     for i in &arr{
       println!("{}", i)
   }
}

如果不使用元素的引用来遍历元素。直接遍历的话,vector将会失去那一片内存的控制权

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


   for i in v{   //v将失去这块内存得所有权
       println!("{}", i)
   }

   for i in v{  //error[E0382]: use of moved value: `v`
       println!("{}", i)
   }

}

存储不同类型的元素:vector结合enum

enum SpreedsheetCell{
      Int(i32),
      Float(f64),
      Text(String),
  }

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

参考:https://kaisery.gitbooks.io/rust-book-chinese/content/content/Vectors.html

https://kaisery.gitbooks.io/rust-book-chinese/content/content/Vectors.html



上一篇:Rust 字符串
下一篇:rust数学运算向上取整向下取整

The minute you think of giving up, think of the reason why you held on so long.