Rust 集合
Rust 的标准集合库提供了最常见的通用编程数据结构的高效实现。本章讨论了常用集合 Vector、HashMap 和 HashSet 的实现。
Vector
Vector 是一个可调整大小的数组。它在连续的内存块中存储值。可以使用预定义结构 Vec 来创建向量。Vector 的一些重要特点包括:
- 向量在运行时可以增长或缩小。
-
向量是一个同质的集合。
-
向量将数据按照特定顺序作为一系列元素存储。向量中的每个元素都被分配一个唯一的索引号。索引从 0 开始,一直到 n-1,其中 n 是集合的大小。例如,在有 5 个元素的集合中,第一个元素的索引为 0,最后一个元素的索引为 4。
-
向量仅将值追加到(或接近)末尾。换句话说,向量可用于实现栈。
-
向量的内存在堆中分配。
语法 – 创建一个 Vector
let mut instance_name = Vec::new();
Vec结构体的静态方法new()用于创建一个向量实例。
另外,也可以使用vec!宏来创建向量。语法如下所示:
let vector_name = vec
![val1,val2,val3]
以下表格列出了Vec结构体的一些常用函数。
编号 | 方法 | 签名和描述 |
---|---|---|
1 | new() | **pub fn new()- >Vect ** 构建一个新的空Vec。在元素被推送到Vec之前,它不会分配内存。 |
2 | push() | **pub fn push( &mut self, value: T) ** 将一个元素添加到集合的末尾。 |
3 | remove() | **pub fn remove( &mut self, index: usize) -> T ** 删除并返回向量中位置为index的元素,并将其后的所有元素向左移动。 |
4 | contains() | **pub fn contains( &self, x: &T) -> bool ** 如果切片包含给定值的元素,则返回true。 |
5 | len() | **pub fn len( &self) -> usize ** 返回向量中的元素数量,也称为其’长度’。 |
示例:创建一个矢量 – new()
要创建一个矢量,我们使用静态方法 new −
fn main() {
let mut v = Vec::new();
v.push(20);
v.push(30);
v.push(40);
println!("size of vector is :{}",v.len());
println!("{:?}",v);
}
上面的示例使用定义在结构体 Vec 中的静态方法 new() 创建了一个 Vector。push(val) 函数将参数值添加到集合中。len() 函数返回向量的长度。
输出
size of vector is :3
[20, 30, 40]
示例:使用vec!宏创建向量
以下代码使用vec!宏创建一个向量。向量的数据类型会根据首个赋值给它的值进行推断。
fn main() {
let v = vec
![1,2,3];
println!("{:?}",v);
}
输出
[1, 2, 3]
如前所述,一个向量只能包含相同数据类型的值。以下代码段将会报错[E0308]: 类型不匹配错误。
fn main() {
let v = vec
![1,2,3,"hello"];
println!("{:?}",v);
}
示例:push()
在集合的末尾添加一个元素。
fn main() {
let mut v = Vec::new();
v.push(20);
v.push(30);
v.push(40);
println!("{:?}",v);
}
输出
[20, 30, 40]
示例: remove()
移除并返回向量中位置索引为index的元素,同时将其后的所有元素向左移动。
fn main() {
let mut v = vec
![10,20,30];
v.remove(1);
println!("{:?}",v);
}
输出
[10, 30]
示例 – contains()
如果切片中包含具有给定值的元素,则返回真 –
fn main() {
let v = vec
![10,20,30];
if v.contains(&10) {
println!("found 10");
}
println!("{:?}",v);
}
输出
found 10
[10, 20, 30]
示例: len()
返回向量中的元素数量,也称为其“长度”。
fn main() {
let v = vec
![1,2,3];
println!("size of vector is :{}",v.len());
}
输出
size of vector is :3
从向量中获取值
可以使用相应的索引号访问向量中的各个元素。以下示例创建了一个向量并打印了第一个元素的值。
fn main() {
let mut v = Vec::new();
v.push(20);
v.push(30);
println!("{:?}",v[0]);
}
Output: `20`
使用对集合的引用也可以获取向量中的值。
fn main() {
let mut v = Vec::new();
v.push(20);
v.push(30);
v.push(40);
v.push(500);
for i in &v {
println!("{}",i);
}
println!("{:?}",v);
}
输出
20
30
40
500
[20, 30, 40, 500]
哈希映射
哈希映射是一种键值对的集合(称为条目)。在哈希映射中,没有两个条目可以有相同的键。简而言之,哈希映射是一个查找表。哈希映射将键和值存储在哈希表中。条目以任意顺序存储。键用于在哈希映射中搜索值。哈希映射结构定义在 std::collections 模块中。要访问哈希映射结构,必须显式地导入该模块。
语法:创建一个哈希映射
let mut instance_name = HashMap::new();
HashMap结构的静态方法new()用于创建一个HashMap对象。此方法创建一个空的HashMap。
下面讨论了HashMap的常用函数:
Sr.No | 方法 | 签名和描述 |
---|---|---|
1 | insert() | **pub fn insert( &mut; self, k: K, v: V) -> Option ** 插入一个键/值对,如果没有键则返回None。更新后,返回旧值。 |
2 | len() | **pub fn len( &self;) -> usize ** 返回映射中的元素数量。 |
3 | get() | **pub fn get |
4 | iter() | **pub fn iter( &self;) -> Iter ** 以任意顺序访问所有键值对的迭代器。迭代器的元素类型是(&’a K, &’a V)。 |
5 | contains_key | **pub fn contains_key (&self;, k: &Q;) -> bool ** 如果映射包含指定键的值,则返回true。 |
6 | remove() | **pub fn remove_entry (&mut; self, k: &Q;) -> Option<(K, V)> ** 从映射中删除一个键,并返回之前在映射中的存储的键和值。 |
示例: insert()
往HashMap中插入一个键/值对。
use std::collections::HashMap;
fn main(){
let mut stateCodes = HashMap::new();
stateCodes.insert("KL","Kerala");
stateCodes.insert("MH","Maharashtra");
println!("{:?}",stateCodes);
}
上面的程序创建一个HashMap并用2个键值对进行初始化。
输出
{"KL": "Kerala", "MH": "Maharashtra"}
示例:len()
返回地图的元素数量
use std::collections::HashMap;
fn main() {
let mut stateCodes = HashMap::new();
stateCodes.insert("KL","Kerala");
stateCodes.insert("MH","Maharashtra");
println!("size of map is {}",stateCodes.len());
}
上面的示例创建了一个HashMap并打印其中元素的总数。
输出
size of map is 2
示例- get()
返回对应于键的值的引用。以下示例在HashMap中检索键为KL的值。
use std::collections::HashMap;
fn main() {
let mut stateCodes = HashMap::new();
stateCodes.insert("KL","Kerala");
stateCodes.insert("MH","Maharashtra");
println!("size of map is {}",stateCodes.len());
println!("{:?}",stateCodes);
match stateCodes.get(&"KL") {
Some(value)=> {
println!("Value for key KL is {}",value);
}
None => {
println!("nothing found");
}
}
}
输出
size of map is 2
{"KL": "Kerala", "MH": "Maharashtra"}
Value for key KL is Kerala
示例− iter()
返回一个包含对所有键值对的引用的迭代器,按任意顺序排列。
use std::collections::HashMap;
fn main() {
let mut stateCodes = HashMap::new();
stateCodes.insert("KL","Kerala");
stateCodes.insert("MH","Maharashtra");
for (key, val) in stateCodes.iter() {
println!("key: {} val: {}", key, val);
}
}
输出
key: MH val: Maharashtra
key: KL val: Kerala
示例:contains_key()
如果Map包含指定键的值,则返回true。
use std::collections::HashMap;
fn main() {
let mut stateCodes = HashMap::new();
stateCodes.insert("KL","Kerala");
stateCodes.insert("MH","Maharashtra");
stateCodes.insert("GJ","Gujarat");
if stateCodes.contains_key(&"GJ") {
println!("found key");
}
}
输出
found key
示例: remove()
从地图中移除一个键。
use std::collections::HashMap;
fn main() {
let mut stateCodes = HashMap::new();
stateCodes.insert("KL","Kerala");
stateCodes.insert("MH","Maharashtra");
stateCodes.insert("GJ","Gujarat");
println!("length of the hashmap {}",stateCodes.len());
stateCodes.remove(&"GJ");
println!("length of the hashmap after remove() {}",stateCodes.len());
}
输出
length of the hashmap 3
length of the hashmap after remove() 2
HashSet(哈希集)
HashSet是一组唯一类型为T的值。添加和删除值很快,并且快速判断给定的值是否在集合中。 HashSet结构定义在std::collections模块中。为了访问HashSet结构,需要显式导入此模块。
语法:创建HashSet
let mut hash_set_name = HashSet::new();
静态方法 new 用于创建一个 HashSet 数据结构。这个方法会创建一个空的 HashSet。
下表列出了一些常用的 HashSet 数据结构方法。
Sr.No | 方法 | 签名和描述 |
---|---|---|
1 | insert() | **pub fn insert( &mut; self, value: T) -> bool ** 向集合中添加一个值。如果集合中没有这个值,返回true,否则返回false。 |
2 | len() | **pub fn len( &self;) -> usize ** 返回集合中元素的数量。 |
3 | get() | **pub fn get (&self;, value: &Q;) -> Option<&T;> where T: Borrow, Q: Hash + Eq, ** 如果存在等于给定值的值,则返回集合中该值的引用。 |
4 | iter() | **pub fn iter( &self;) -> Iter ** 以任意顺序访问所有元素的迭代器。迭代器元素的类型是&’a T。 |
5 | contains_key | **pub fn contains (&self;, value: &Q;) -> bool ** 如果集合中包含一个值,返回true。 |
6 | remove() | **pub fn remove (&mut; self, value: &Q;) -> bool ** 从集合中删除一个值。如果值存在于集合中,则返回true。 |
示例- insert()
向集合中添加一个值。HashSet不会将重复的值添加到集合中。
use std::collections::HashSet;
fn main() {
let mut names = HashSet::new();
names.insert("Mohtashim");
names.insert("Kannan");
names.insert("TutorialsPoint");
names.insert("Mohtashim");//duplicates not added
println!("{:?}",names);
}
输出
{"TutorialsPoint", "Kannan", "Mohtashim"}
示例:len()
返回集合中元素的数量。
use std::collections::HashSet;
fn main() {
let mut names = HashSet::new();
names.insert("Mohtashim");
names.insert("Kannan");
names.insert("TutorialsPoint");
println!("size of the set is {}",names.len());
}
输出
size of the set is 3
示例- iter()
iter()函数返回一个以任意顺序访问所有元素的迭代器。
use std::collections::HashSet;
fn main() {
let mut names = HashSet::new();
names.insert("Mohtashim");
names.insert("Kannan");
names.insert("TutorialsPoint");
names.insert("Mohtashim");
for name in names.iter() {
println!("{}",name);
}
}
结果
TutorialsPoint
Mohtashim
Kannan
示例: get()
返回与给定值相等的集合中的值的引用,如果有的话。
use std::collections::HashSet;
fn main() {
let mut names = HashSet::new();
names.insert("Mohtashim");
names.insert("Kannan");
names.insert("TutorialsPoint");
names.insert("Mohtashim");
match names.get(&"Mohtashim"){
Some(value)=>{
println!("found {}",value);
}
None =>{
println!("not found");
}
}
println!("{:?}",names);
}
输出
found Mohtashim
{"Kannan", "Mohtashim", "TutorialsPoint"}
示例 – contains()
如果集合包含一个值则返回真。
use std::collections::HashSet;
fn main() {
let mut names = HashSet::new();
names.insert("Mohtashim");
names.insert("Kannan");
names.insert("TutorialsPoint");
if names.contains(&"Kannan") {
println!("found name");
}
}
输出
found name
示例: remove()
从集合中删除一个值。
use std::collections::HashSet;
fn main() {
let mut names = HashSet::new();
names.insert("Mohtashim");
names.insert("Kannan");
names.insert("TutorialsPoint");
println!("length of the Hashset: {}",names.len());
names.remove(&"Kannan");
println!("length of the Hashset after remove() : {}",names.len());
}
输出
length of the Hashset: 3
length of the Hashset after remove() : 2