我的RUST学习——【第八章 8-1】容器 Vector

Vec<T> ,我们的老朋友了,废话不多说,直接开始讲用法。

创建vector

标准创建

创建一个空的vector,由于是空的,编译器无法进行类型推断,因此必须要手动声明类型。

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

vec宏创建

一般情况下,一旦插入值就可以推断类型,因此我们使用宏来创建。

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

更新vector

let mut v = Vec::new();
v.push(5);

必须使用 mut 关键字使其可变,这种是利用上下文进行推断。

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

类似于任何其他 struct ,vector 在离开作用域时会被释放。

{
	let v = vec![1, 2, 3, 4];
} // <- v 会被丢弃

当 vector 被丢弃时,所有其内容也会被丢弃,这意味着这里它包含的整数将被清理。这可能看起来非常直观,不过一旦开始使用 vector 元素的引用,情况就变得有些复杂了。下面让我们处理这种情况!

读取 vector 的元素,内部元素的悬垂指针

两种方法

  • 直接通过索引获取 &[idx],返回一个引用。
  • 通过 get 和索引,返回一个 Option<&T>
let v = vec![1,2,3,4,5];

let thrid: &i32 = &v[2];

match v.get(2) {
	Some(thrid) => (),
	None => ()
}

这两种方式,程序可以选择如何处理当索引值越界的情况。

  • 当使用第一种方式时,如果触发越界,会抛出一个panic。该方式适合的语义是——此时越界触发了严重的错误,应该时程序崩溃停止。
  • 当使用第二种方式时,如果触发越界,就返回一个 None ,可以继续进行处理 Some(&element),只不过单独需要处理一下 None 的情况。

一旦程序获取了一个有效的引用,借用检查器将会执行所有权和借用规则(第四章讲到)来确保 vector 内容的这个引用和任何其他引用保持有效。回忆一下不能在相同作用域中同时存在可变和不可变引用的规则,以及不可变引用的最后一次使用必须在可变引用之前这个规则。这些规则适用于示例 8-7,当我们获取了 vector 的第一个元素的不可变引用并尝试在 vector 末尾增加一个元素的时候,这是行不通的:

示例 8-7
let mut v = vec![1,2,3,4];
let first = &v[0];
v.push(5);

原因是,rust 容器扩容的原理和大多数语言一样,当容器的cap需要扩容,且当前堆空间大小不够时,会重新寻找一片连续的空间,此时 v 指向的内存会被清空,但是first依然指向那片区域,造成了垂悬指针。

遍历 vector 中的元素

一个普通的遍历。

let v = vec![12,33,44,14,122];
for i in &v {
	println!("{}", i);
}

一个希望修改内容的可变遍历。

let mut v = vec![100, 32, 57];
let i in &mut v {
	*i += 50;
	println!("{}", i); // 只是访问的话不需要加 *
}

使用枚举来储存多种类型

一开始提到,vector 只能存储相同类型的值。这是很不方便的。幸运的是,枚举成员都被定义为相同的枚举类型,所以当需要在 vector 中存储不同类型的值时,可以使用枚举。

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

let row = vec![
    Multiple::Int(1),
    Multiple::Float(3.14),
    Multiple::Text(String::from("hello")),
];

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

现在我们了解了一些使用 vector 的最常见的方式,请一定去看看标准库中 Vec 定义的很多其他实用方法的 API 文档。例如,除了 push 之外还有一个 pop 方法,它会移除并返回 vector 的最后一个元素。让我们继续下一个集合类型:String

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值