Rust - 集合

Rust 的标准集合库提供了最常见的通用编程数据结构的高效实现。 本章讨论常用集合的实现 − 向量(Vector)、哈希映射(HashMap) 和哈希集(HashSet)。

向量(Vector)

向量是一个可调整大小的数组。 它将值存储在连续的内存块中。 预定义结构 Vec 可用于创建向量。 Vector 的一些重要特征是 −

  • 向量可以在运行时增大或缩小。

  • 向量是同构集合。

  • 向量将数据存储为按特定顺序排列的元素序列。 Vector 中的每个元素都分配有一个唯一的索引号。 索引从 0 开始一直到 n-1,其中 n 是集合的大小。 例如,在 5 个元素的集合中,第一个元素将位于索引 0,最后一个元素将位于索引 4。

  • 向量只会将值附加到(或接近)末尾。 换句话说,向量可以用来实现栈。

  • 向量的内存在堆中分配。

语法 - 创建向量

let mut instance_name = Vec::new();

Vec结构体的静态方法new()用于创建向量实例。

或者,也可以使用 vec! 宏创建向量。 语法如下所示 −

let vector_name = vec![val1,val2,val3]

下表列出了Vec结构的一些常用函数。

Sr.No 方法 函数 & 描述
1 new()

pub fn new()->Vect

构造一个新的空 Vec。 在将元素推入向量之前,向量不会分配。

2 push()

pub fn push(&mut self, value: T)

将元素附加到集合的后面。

3 remove()

pub fn remove(&mut self, index: usize) -> T

删除并返回向量中位置索引处的元素,将其后面的所有元素向左移动。

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]

如前所述,向量只能包含相同数据类型的值。 以下代码片段将引发error[E0308]: mismatched types(错误[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()

删除并返回向量中位置索引处的元素,将其后面的所有元素向左移动。

fn main() {
   let mut v = vec![10,20,30];
   v.remove(1);
   println!("{:?}",v);
}

输出

[10, 30]

示例 - contains()

如果切片包含具有给定值的元素,则返回 true −

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]

哈希映射(HashMap)

映射是键值对(称为条目)的集合。 映射中的两个条目不能具有相同的键。 简而言之,映射就是一个查找表。 哈希映射将键和值存储在哈希表中。 条目以任意顺序存储。 键用于在哈希映射中搜索值。 HashMap 结构在 std::collections 模块中定义。 应显式导入此模块以访问 HashMap 结构。

语法:创建哈希映射

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<Q: ?Sized>(&lself, k: &Q) -> Option<&V> where K:Borrow Q:Hash+ Eq

返回对与键对应的值的引用。

4 iter()

pub fn iter(&self) -> Iter<K, V>

以任意顺序访问所有键值对的迭代器。 迭代器元素类型是(&'a K, &'a V)。

5 contains_key

pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool

如果映射包含指定键的值,则返回 true。

6 remove()

pub fn remove_entry<Q: ?Sized>(&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"}

Illustration: len()

Returns the number of elements in the map

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()

如果映射包含指定键的值,则返回 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)

哈希集是T类型的唯一值的集合。添加和删除值的速度很快,并且询问给定值是否在集合中也很快。 HashSet 结构在 std::collections 模块中定义。 应显式导入此模块以访问 HashSet 结构。

语法:创建哈希集

let mut hash_set_name = HashSet::new();

HashSet结构的静态方法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<Q:?Sized>(&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<Q: ?Sized>(&self, value: &Q) -> bool

如果集合包含值,则返回 true。

6 remove()

pub fn remove<Q: ?Sized>(&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");//未添加重复项

   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()

返回一个以任意顺序访问所有元素的迭代器。

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()

如果集合包含值,则返回 true。

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