Rust编程语言-常用集合-Vector
Vector存储列表
- Vector写法是:Vec<T>
- 由标准库提供,代码中可以直接使用,不用引入路径
- 可以存储多个值
- 只能存放相同类型的数据
- 多个值在内存中连续存放
创建Vector
- Vec::new函数
fn main() {
let v: Vec<i32> = Vec::new();
}
- 通常使用初始值来创建Vec<T>,这样就可以使用vec! 宏来创建Vector了
fn main() {
let v = vec![1, 2, 3];
}
更新Vector
- 向Vector添加元素,使用push方法
fn main() {
// 使用 mut 申明是可变的,这样我们才能插入元素
// 这里没有指定类型,因为接着就插入了值,rust能够推断类型
// 如果没有插入数据,因为没有指定类型,编译通不过
let mut v = Vec::new();
v.push(5);
v.push(6);
v.push(7);
v.push(8);
}
删除 Vector
- 与任何其它struct一样,当Vector离开作用域后,vector会被清理掉,它里面的元素也会被清理掉
读取Vector的元素
- 第一种方式:使用索引的方式读取,如果读取超出索引范围的数据会抛出异常
- 第二种方式:使用get方法,超出范围的值不会异常,而是None,因为get返回的是Option
fn main() {
let v = vec![1, 2, 3, 4, 5];
let third: &i32 = &v[2];
println!("The third element is {third}");
let third: Option<&i32> = v.get(2);
match third {
Some(third) => println!("The third element is {third}"),
None => println!("There is no third element."),
}
}
vector所有权和借用规则
- 不能在同一作用域内同时拥有某个值的可变和不可变引用
fn main() {
let mut v = vec![1, 2, 3, 4, 5];
// 产生一个不可变引用
let first = &v[0];
// 产生可变引用
v.push(6);
// 这里再使用不可变引用,就会出问题了,除非在可变引用之后不再使用first不可变引用
println!("The first element is: {first}");
}
first引用的是第0个,而我们向vector末尾添加元素,为什么不可以呢?
因为vector在内存中是连续存放的,当我们再次向内存中添加元素,所在空间不够时,会对内存进行重新分配,找一块足够的空间。这样原先存放的地址就会被释放,这时 first 还是指向释放的空间,就有问题了。
遍历Vector中的值
- for 循环
fn main() {
let v = vec![100, 32, 57];
for i in &v {
println!("{i}");
}
}
遍历修改vector的值:
fn main() {
// 声明成可变
let mut v = vec![100, 32, 57];
// 引用也必须可变
for i in &mut v {
// *i 是对i解引用,从而可以获取到引用对应的值,因为i对应的是地址 *i才是值
*i += 50;
}
}
值就变成了 [150, 82, 107]
Vector + enum
因为vector只能存放相同元素值,这很不方便。好在enum的成员在rust中被认为是相同的枚举类型,所以当需要在 vector 中储存不同类型值时,我们可以定义并使用一个枚举!
- enum的变体可以附加不同类型的数据
- enum的变体定义在同一个enum类型下
fn main() {
// excel 单元格存放类型
enum SpreadsheetCell {
Int(i32),
Float(f64),
Text(String),
}
let row = vec![
SpreadsheetCell::Int(3),
SpreadsheetCell::Text(String::from("blue")),
SpreadsheetCell::Float(10.12),
];
}
Rust 在编译时就必须准确的知道 vector 中类型的原因在于它需要知道储存每个元素到底需要多少内存。第二个好处是可以准确的知道这个 vector 中允许什么类型。如果 Rust 允许 vector 存放任意类型,那么当对 vector 元素执行操作时一个或多个类型的值就有可能会造成错误。使用枚举外加 match 意味着 Rust 能在编译时就保证总是会处理所有可能的情况,正如第六章讲到的那样。
如果在编写程序时不能确切无遗地知道运行时会储存进 vector 的所有类型,枚举技术就行不通了。相反,你可以使用 trait 对象,后面会学到。
上一篇:C++ vector 简介
下一篇:Java集合类之Vector