【RUST学习日记】第11课 向量 (下)

简介: 【RUST学习日记】第11课 向量 (下)

0x00 回顾与开篇


上一篇文章只是简单介绍了下向量的基本概念和常用方法——增删改。本篇文章继续来介绍向量。

 

0x01 访问元素


Rust中也存在两种方式去访问向量中的元素。

1、使用“向量名称[索引]”的方式访问指定元素,类似于修改元素的访问。如果传入的索引大于向量的长度,则会产生程序错误,常称作数组越界

示例代码如下:

let vec_find = vec![1, 2, 3];
    dbg!(vec_find[0]);
    dbg!(vec_find[1]);
    dbg!(vec_find[2]);

代码执行结果:

[src\main.rs:44] vec_find[0] = 1
[src\main.rs:45] vec_find[1] = 2
[src\main.rs:46] vec_find[2] = 3

2、使用get方法访问元素,传入的参数同样是索引,但是其返回的是Option枚举类型,如果索引越界,不会产生错误,则会返回None。(关于Option这里了解即可)。

示例代码如下:

let vec_get = vec![1, 2, 3];
    dbg!(vec_get.get(0));
    dbg!(vec_get.get(1));
    dbg!(vec_get.get(2));
    // 下面代码不会产生错误,正常执行
    dbg!(vec_get.get(3));

代码执行结果:

[src\main.rs:52] vec_get.get(0) = Some(
    1,
)
[src\main.rs:53] vec_get.get(1) = Some(
    2,
)
[src\main.rs:54] vec_get.get(2) = Some(
    3,
)
[src\main.rs:56] vec_get.get(3) = None


0x02 向量容量的变化


向量容量增长策略


向量的容量(Capacity)是指为存储元素所分配的空间。向量的长度(Length)如果大于其当前的容量,则会发生重新分配空间的操作,这个过程比较耗时。假设当前数组的容量为5,如果向量内的元素小于等于5个,则其容量不会增加,如果元素超过5个,则向量的容量就会重新分配,在原有的基础上乘以2(目前2是向量的增长因子),最后容量会变成10。因此尽可能的在初始化时为其指定合适的容量。

可以通过len()方法获取向量的长度,capacity()方法获取向量的容量,容量变化的示例代码如下:

let mut vec_capacity :Vec<i32> = Vec::with_capacity(5);
    // 动态增长
    println!("vec_capacity 填充元素前的长度为 {}", vec_capacity.len());
    println!("vec_capacity 填充元素前的容量为 {}", vec_capacity.capacity());
    // 关于循环这里了解即可,这里的意思是,填充0,1,2,3,4五个元素
    for i in 0..5 {
        vec_capacity.push(i);
    }
    println!("vec_capacity 填充5个元素后的长度为 {}", vec_capacity.len());
    println!("vec_capacity 填充5个元素后的容量为 {}", vec_capacity.capacity());
    // 填充第6个元素
    vec_capacity.push(5);
    println!("vec_capacity 填充6个元素后的长度为 {}", vec_capacity.len());
    println!("vec_capacity 填充6个元素后的容量为 {}", vec_capacity.capacity());

代码执行结果:

vec_capacity 填充元素前的长度为 0
vec_capacity 填充元素前的容量为 5
vec_capacity 填充5个元素后的长度为 5
vec_capacity 填充5个元素后的容量为 5
vec_capacity 填充6个元素后的长度为 6
vec_capacity 填充6个元素后的容量为 10


首次填充元素的默认容量


咱们再来看另外一个问题,假设创建一个容量为0的向量,然后向其中添加元素,这时容量会变成多少呢?

示例代码如下:

let mut vec_default: Vec<i32> = Vec::new();
    println!("vec_default 的长度为 {}", vec_default.len());
    println!("vec_default 的容量为 {}", vec_default.capacity());
    vec_default.push(1);
    println!("vec_default 添加一个元素的长度为 {}", vec_default.len());
    println!("vec_default 添加一个元素的容量为 {}", vec_default.capacity());

代码执行结果:

vec_default 的长度为 0
vec_default 的容量为 0
vec_default 添加一个元素的长度为 1
vec_default 添加一个元素的容量为 4

从上面程序的运行结果,可以得知,首次创建空容量的向量,向其中添加一个元素后,则会将容量变调整为4。之后的容量调整则遵循增长因子为2的规则。


0x03 数组与向量的区别


  • 原生数组(Array)的签名是[T;N],而向量(Vector)的签名是Vec<T>
  • 原生数组(Array)的大小是在编译时确定的常量,也是类型自身的一部分。其大小不更改,不能向数组中增加或者缩短数组的长度。向量(Vector)是一种可以动态分配增长或者缩减的数组,在运行时才会确定向量的长度。
  • 原生数组(Array)的元素可以在上存储,而向量(Vector)的元素只能在上分配。

 

0x04 小结


其实Vec<T>包好了3个值:分别是:对分配在对上用于保存元素的缓冲区的引用,该缓冲区可以存储元素的个数(Capacity),当前实际存储的元素个数(Length)。如果提前知道向量的容量,推荐使用Vec::with_capacity。现在知道了向量是由三部分组成,那么它在内存中的模型是什么样的呢?关于向量和数组该如何遍历?排序?其它高级用法?这一系列的问题将会在后续章节一一介绍,这节课仅仅是简单介绍了向量这种数据类型。

相关文章
|
4天前
|
Rust 算法 安全
学习Rust
【10月更文挑战第13天】学习Rust
28 8
|
5天前
|
Rust 安全 算法
Rust的学习
【10月更文挑战第12天】Rust的学习
13 2
|
5天前
|
Rust 算法 安全
如何学习Rust编程?
【10月更文挑战第12天】如何学习Rust编程?
17 1
|
17天前
|
Rust API
【Rust学习】09_方法语法
结构体让你可以创建出在你的领域中有意义的自定义类型。通过结构体,我们可以将相关联的数据片段联系起来并命名它们,这样可以使得代码更加清晰。在 impl 块中,你可以定义与你的类型相关联的函数,而方法是一种相关联的函数,允许您指定结构体的实例具有的行为。 但是结构体并不是创建自定义类型的唯一方式:让我们转向 Rust 的 enum 功能,将另一个工具添加到你的工具箱中。
10 0
|
1月前
|
Rust 索引
【Rust学习】08_使用结构体代码示例
为了了解我们何时可能想要使用结构体,让我们编写一个计算长方形面积的程序。我们将从使用单个变量开始,然后重构程序,直到我们改用结构体。
72 2
|
1月前
|
存储 Rust 编译器
【Rust学习】07_结构体说明
**struct**或 ***structure***是一种自定义数据类型,允许您命名和包装多个相关的值,从而形成一个有意义的组合。如果您熟悉面向对象的语言,那么**struct**就像对象中的数据属性。在本章中,我们将比较和对比元组与结构体,在您已经知道的基础上,来演示结构体是对数据进行分组的更好方法。
21 1
|
28天前
|
存储 Rust 安全
30天拿下Rust之向量
30天拿下Rust之向量
22 0
|
1月前
|
Rust Linux Go
Rust/Go语言学习
Rust/Go语言学习
|
2月前
|
存储 Rust 安全
【Rust学习】06_切片
所有权、借用和切片的概念确保了 Rust 程序在编译时的内存安全。Rust 语言提供了跟其他系统编程语言相同的方式来控制你使用的内存,但拥有数据所有者在离开作用域后自动清除其数据的功能意味着你无须额外编写和调试相关的控制代码。
21 1
|
3月前
|
存储 Rust 安全
【Rust学习】04_所有权
所有权是 Rust 最独特的特性,对语言的其余部分有着深远的影响。它使 Rust 能够在不需要垃圾收集器的情况下保证内存安全,因此了解所有权的运作方式非常重要。在本章中,我们将讨论所有权以及几个相关功能:借用、切片以及 Rust 如何在内存中布局数据。
21 1