Rust中的容器
- 前言
- Vector原理以及使用方法
- HashMap原理以及使用方法
-
-
- [常用操作: 创建,插入,删除,查找](#常用操作: 创建,插入,删除,查找)
-
- 总结
前言
容器即将一系列具有相同特征的数据存储在一起。在编程过程中,开发者使用到的容器种类、原理以及使用方式基本相同。
Rust最常用的两个容器:
- Vector
- HashMap
Rust中其他的容器:
双端队列:VecDeque
链表:LinkedList
映射:BtreeMap
集合:HashSet,BtreeSet
其他:BinaryHeap
Vector原理以及使用方法
Rust中的Vector和C++中的Vector基本一致,都可以动态扩展,都是二倍增加,都是紧密排列,都可以指定容量,非常适合在不确定数据量大小时候使用。
与之对应的是array,与C++并无二致,在声明期需要确定大小,且使用期间不可变,适合固定大小的数据,如月份等。
特点在于,rust中的vector必然要遵守rust的所有权规则
- 与在rust中的其他的变量一致,当数组nums超出作用域之后,将被回收。
代码示例:
rust
{
let nums = vec![1,1,1];
}
println!("{:?}", nums); //将会报错,因为nums已经超出作用域
- rust中读取数组中的元素方式,与C++类似,既支持了index访问形式,也支持了方法访问,C++使用at(index),Rust使用get(index),不同的是at如果超出了C++动态数组的大小,会抛出异常Out of Range ,而Get方法在Rust中会返回一个Option值 ,更安全的交给开发者做出反应。所以index适合开发者完全确认不会越界的情况下使用,而get(),适合避免越界的情况下使用。
代码示例:
rust
fn main() {
let nums = vec![1, 3, 2, 4, 5];
let second = &nums[1];
println!("{second}");
let first = nums.get(0);
match first {
Some(vfirst) => println!("{}", vfirst),
None => println!("nothing found"),
}
}
- 代码示例:
rust
fn main() {
let mut nums = vec![1, 2, 3, 4, 5];
let num = &nums[1];
nums.push(6);
println!("{num}");
}
在Rust中的借用和引用一章中,提到过在同一作用域下,可变不可变不能同时出现。结合上述代码,问题会出现在:
rust
nums.push(6);
println!("{num}");
也就是动态数组中的元素在可变引用后使用了不可变引用,将会报错:
cannot borrow nums as mutable because it is also borrowed as immutable
如此严格的原因正是由于rust的安全性,vector是可以扩展的,当push后vector扩展后将会发生内存地址变化,原来不可变引用便会失效。
- 有关数组的排序,初始化等不在赘述,这里有个比较重要的点需要举例说明。在泛型与特征对象中我们提到过,当特征trait作为函数返回值时,返回值无法返回不同类型的对象Rust的泛型与特征,由此展开了特征对象的概念(形如Box),使用vector时我们一般也不会仅仅存储简单类型,而是根据需求存储,具有同类特征的类型对象便是非常常用的存储方式。
代码示例:
rust
trait Name {
fn name(&self);
}
struct Dog {
name: String,
}
struct Cat {
name: String,
}
impl Name for Dog {
fn name(&self) {
println!("The dog's name is: {}", self.name);
}
}
impl Name for Cat {
fn name(&self) {
println!("The cat's name is: {}", self.name);
}
}
fn main() {
let animalvec: Vec<Box<dyn Name>> = vec![
Box::new(Dog {
name: "Rex".to_string(),
}),
Box::new(Cat {
name: "Whiskers".to_string(),
}),
Box::new(Dog {
name: "Buddy".to_string(),
}),
];
for animal in &animalvec {
animal.name();
}
}
HashMap原理以及使用方法
Hashmap在其他语言中也及其常见和常被使用,都是使用hashtable存储键值对,并通过链式存储解决hash冲突,查找速度极快O(1).
常用操作: 创建,插入,删除,查找
代码示例:
rust
use std::collections::HashMap;
fn main() {
let mut mymap = HashMap::new();//创建
mymap.insert(1, "cat");//插入
mymap.insert(2, "dog");
mymap.insert(3, "fish");
mymap.remove(&2);//删除
let cat = mymap[&1];//查询
println!("{cat}");
println!("{:?}", mymap); // Output: {2: "cat", 3: "fish"}
mymap.insert(3, "Dog");//原值更新
println!("{:?}", mymap); // Output: {2: "dog", 3: "cat"}
}
总结
上述是Rust中最最常用的两个容器的基本原理概述和使用方法和注意事项,后续会更新未说明的剩余的容器的使用方法和原理概述。
如有勘误,敬请指出。