1. rust标准集合
集合是常用的数据结构,rust提供了二类标准集合:
- 线性集合:Vec、VecDeque、LinkList
- 复杂集合:BinaryHeap、HashMap、HashSet、BTreeMap、BTreeSet
要想踏过rust的使用关,就需要熟练使用标准集合
2. Vec、VecDeque
Vec是可增长数组,由三元组表达-> ptr(指向堆中的实际存储数据)、长度、容量,在rust中的类型为vec;学习vec,需要与数组和切片对比。
数组[]在rust的定义为array,其数据存在栈中,数组大小不能变化了,因此可以查看array的函数手册,发现没有任何操作可改变array的大小。
切片在rust定义为slice,vec和array通过&均可转为切片。
2.1 vec基本操作
创建Vec
let words = vec!["step", "on", "no", "pets"]; // 使用给定内容创建一个向量
let mut buffer = vec![0u8; 1024]; // 1024个内容为0的字节
对Vec元素访问
- 遍历 Vec<T> 或数组 [T; N] 会生成 T 类型的条目。这些元素会逐个从向量或数组中移动出来并被消耗掉。
- 遍历 &[T; N]、&[T] 或 &Vec<T> 类型的值(对数组、切片或向量的引用)会生成 &T 类型的条目,即对单个元素的引用,这些元素不会移动出来。
- 遍历 &mut [T; N]、&mut [T] 或 &mut Vec<T> 类型的值会生成 &mut T 类型的条目。
值的插入删除
vec.push(value)(推入)
vec.pop()(弹出)
vec.insert(index, value)(插入)
vec.remove(index)(移除)
vec.extend(iterable)(扩展)vec2仍然存在
vec.append(&mut vec2)(追加)追加完vec2会被清空
** 其它操作**
vec.retain(test)(留下)// test 参数是实现了 FnMut(&T) -> bool 的函数或闭包
vec.dedup()(去重)// 去重只去相邻的元素
2.2 VecDeque
VecDeque是双端队列,在两端都可以进行操作入队和出队
操作
deque.push_front(value)(队首推入)
deque.push_back(value)(队尾推入)
deque.pop_front()(队首弹出)
deque.pop_back()(队尾弹出)
deque.front()(队首)和 deque.back()(队尾)
3. HashMap、HashSet
3.1 HashMap
HashMap常用操作
map.len()(长度)
map.is_empty()(为空?)
map.contains_key(&key)(包含 key?)
map.get(&key)(按 key 获取)// 返回option
map.get_mut(&key)(按 key 获取,可变版)
map.extend(iterable)(用 iterable 扩展)// map2存在
map.append(&mut map2)(从 map2 追加)// map2清空
map.remove(&key)(按 key 移除值)
map.remove_entry(&key)(按 key 移除条目)
map迭代操作
- 按值迭代(for (k, v) in map)以生成 (K, V) 对。这会消耗 Map。
- 按共享引用迭代(for (k, v) in &map)以生成 (&K, &V) 对。
- 按可变引用迭代(for (k, v) in &mut map)以生成 (&K, &mut V) 对。
map.keys()(所有键的迭代器
map.values()(所有值的迭代器)
map.values_mut()(所有值的可变迭代器)
map.into_iter()(转为迭代器)
map.into_keys()(转为键迭代器)
map.into_values()(转为值迭代器)
entry的优雅操作
例如一个value为vec的map,如果插入元素,用java代码写,写法如下:
Map myMap = new HashMap<String, ArrayList>();
... // 初始化
// 插入一个元素
if (!myMap.containsKey("aaa")) {
myMap["aaa"] = new ArrayList();
}
myMap["aaa"].add("bbb");
这样一个语句,用rust怎么写
let my_map = HashMap::new();
my_map.entry("aaa").or_insert(vec![]).push("bbb")
rust用一行语句优雅表达,非常漂亮,操作如下
map.entry(key).or_insert(value)(取条目或插入)// 返回&mut value
map.entry(key).or_default() // 插入默认值
map.entry(key).or_insert_with(default_fn)(取条目或借助 default_fn 插入)
map.entry(key).and_modify(closure)(取条目并修改)// 返回entry
3.2 set
set操作
set.len()(长度)
set.is_empty()(为空?)
set.contains(&value)(包含)
set.remove(&value)(移除)
set.get(&value)(取值)
set.take(&value)(拿出值)// 类似remove
set迭代
- 按值迭代(for v in set)会生成 Set 的成员并消耗掉此 Set。
- 按共享引用(for v in &set)迭代会生成对 Set 成员的共享引用。
- 不支持通过可变引用迭代 Set。无法获取对存储在 Set 中的值的可变引用。
set交集并集
set1.intersection(&set2)(交集)
set1.union(&set2)(并集)
set1.symmetric_difference(&set2)(对称差集,异或)
set1.is_disjoint(set2)(有交集?)
set1.is_subset(set2)(是子集?)
set1.is_superset(set2)(是超集?)
4. 小结
rust提供的标准集合和Java、C++类似,其中map的entry设计非常优雅,entry是枚举,通过match枚举,实现map的取值及存值,非常值得学习。
网友评论