Rust集合
Rust的标准集合库提供了最常见的通用编程数据结构的有效实现,本章讨论了常用集合的实现:Vector、HashMap和HashSet。
向量(Vector)
向量(Vector)是可调整大小的数组,它将值存储在连续的内存块中。
预定义的结构体Vec可用于创建向量,向量的一些重要特征是:
向量可以在运行时增长或收缩;
向量是齐次的集合;
向量以特定顺序将数据存储为元素序列。向量中的每个元素都分配有唯一的索引号,索引从0至n-1,其中n是集合的大小。例如,在5个元素的集合中,第一个元素的索引为0,最后一个元素的索引为4;
向量只会将值附加到末端(或末端附近),换句话说,向量可用于实现栈;
向量的内存在堆中分配。
语法-创建向量
let mut instance_name = Vec::new();
Vec 结构体的静态方法 new() 用于创建矢量实例。
另外,也可以使用vec!宏创建向量,语法如下:
let vector_name = vec![val1,val2,val3]
下表列出了Vec结构体的一些常用方法:
序号 | 方法 | 签名与说明 |
---|---|---|
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); }
上面的示例使用静态方法创建一个Vector new() 在结构上定义 Vec . The 推(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。
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
访问向量的值
向量中的各个元素可以使用其相应的索引进行访问,以下示例创建了一个向量v,并打印了第一个元素的值。
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是键值对(称为条目)的集合,任意两个条目不能具有相同的键,HashMap将键和值存储在哈希表中,条目以任意顺序存储,该键用于在HashMap中搜索值,HashMap结构体在std::collections模块中定义,应该显式导入此模块以访问HashMap结构体。
语法:创建一个HashMap
let mut instance_name = HashMap::new();
HashMap 结构体的静态方法 new() 用于创建空的HashMap对象。
下面讨论了HashMap的常用方法:
序号 | 方法 | 签名与说明 |
---|---|---|
1 | insert() | pub fn insert(&mut self, k: K, v: V) -> Option 插入键/值对,如果没有键,则返回None。更新后,将返回旧值。 |
2 | len() | pub fn len(&self) -> usize 返回HashMap中的元素数。 |
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 一个迭代器,以任意顺序访问所有键值对。迭代器元素类型为(&'a K,&'a V)。 |
5 | contains_key | pub fn contains_key 如果映射包含指定键的值,则返回true。 |
6 | remove() | pub fn remove_entry 从HashMap中移除键,如果该键先前在HashMap中,则返回存储的键和值。 |
例子: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()
返回对与键对应的值的引用。下面的示例检索key的值 KL 在HashMap中。
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
HashSet是一组类型T的唯一值,添加和删除值很快,并且能快速查询给定值是否在集合中。HashSet结构体在std :: collections模块中定义,应该显式导入此模块以访问HashSet结构体。
语法:创建一个HashSet
let mut hash_set_name = HashSet::new();
HashSet结构体的静态方法 new() ,用于创建一个空的HashSet。
下表列出了HashSet结构的一些常用方法:
序号 | 方法 | 签名与说明 |
---|---|---|
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 返回以任意顺序访问所有元素的迭代器。迭代器元素类型为&'aT。 |
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("newbiego"); names.insert("Mohtashim");//未添加重复项 println!("{:?}",names); }
{"newbiego", "Kannan", "Mohtashim"}
例子:len()
返回集合中的元素数。
use std::collections::HashSet; fn main() { let mut names = HashSet::new(); names.insert("Mohtashim"); names.insert("Kannan"); names.insert("newbiego"); 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("newbiego"); names.insert("Mohtashim"); for name in names.iter() { println!("{}",name); } }
newbiego Mohtashim Kannan
例子:get()
返回对该集合中的值的引用(如果有),该值等于给定值。
use std::collections::HashSet; fn main() { let mut names = HashSet::new(); names.insert("Mohtashim"); names.insert("Kannan"); names.insert("newbiego"); names.insert("Mohtashim"); match names.get(&"Mohtashim"){ Some(value)=>{ println!("found {}",value); } None =>{ println!("not found"); } } println!("{:?}",names); }
found Mohtashim {"Kannan", "Mohtashim", "newbiego"}
例子-contains()
如果集合包含一个值,则返回true。
use std::collections::HashSet; fn main() { let mut names = HashSet::new(); names.insert("Mohtashim"); names.insert("Kannan"); names.insert("newbiego"); 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("newbiego"); 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