15. rust集合库与迭代器

一、前言

基本的数据结构各种语言都会有自己的实现,rust也不例外。

在rust中,这些数据结构的实现被称作“集合”,被放置在了std::colections中。

内容并不算多,只有4个而已,个人认为Vec也应该算它的一部分,可能是因为其太过于常用,所以直接将其放在了全局,而没有放在该空间内。

至于迭代器,是所有集合所通用的方法,所以也会在本章对其进行讲解。

二、Vec

首先第一个便是用的最多的集合:Vec,也就是动态数组,它可以自动扩容。

初始化它的方式主要有三种:

    let v1: Vec<i32> = Vec::new();
    let v2: Vec<i32> = Vec::with_capacity(1000);
    let v3: Vec<i32> = vec![1, 2, 3];

第一种最常见,就是用new函数创建一个空的本实例。

第二种则是用于事先分配指定容量的数组示例,其内同样为空。

如果你事先知道这个数组里面最多存放指定个数的元素,那么使用第二种方式效率会更高,因为它就无需因空间不够导致重新分配内存、复制数据。

第三种使用vec提供的宏,通过指定元素直接生成带有数据的数组。

一般访问、修改直接用下标即可:

let mut v=vec![1,2,3];
let n=v[2];
v[1]=100;

只是需要注意一下,下标是从0开始的。

至于增加,由于是数组,一般推荐只从末尾追加,但你也可以在任意下标插入元素,只不过效率可能不够好:

fn main() {
    let mut v = vec![1, 2, 3];
    v.push(5); //末尾推入元素5
    v.insert(0, 6); //0号位置插入元素6
}

而删除元素,也有两种方式:

    let mut v = vec![1, 2, 3];
    v.remove(0); //删除0位置元素1
    v.drain(0..1); // 删除[0,1)这个范围中的所有元素

除了上面基本的增删改查操作外,vec还提供了一些有意思的函数,比如分页:

image.png

chunks函数可以用来做分页操作,比如上图中我设置每一页三个,然后使用skip用作”翻页“,本质上就是跳过1页,最后调用next函数获取这一页的数据。

这里的next、skip函数名之所以看起来比较奇怪,是因为它们实际上操作的是迭代器,这一点会在本章后面的内容对其进行介绍。

我们还可以判断某个元素是否存在其中:

v.contains(&4);

三、map

然后要介绍的就是我个人非常常用的集合map,也常常被称为映射。

不同于普通的数组只能通过数字索引去查找相应的元素,map可以实现将任意类型作为索引(key)去查找相应的元素(值)。

这在很多时候都是一个非常有用的特性,虽然其实现原理可能比较繁琐,但它的使用方法还是很简单的:

use std::collections::HashMap;
fn main() {
    let mut map = HashMap::new();
    //插入元素(键值对)
    map.insert("a", "小明");
    //取出元素(根据键取值)
    let name = map["a"];
    //修改元素(如果键存在则覆盖,实现修改)
    map.insert("a", "小红");
    //判断是否包含某个键
    map.contains_key("a");
    //返回个数
    map.len();
    //遍历
    for (k,v) in map.iter() {
        println!("{}:{}",k,v);
    }
    //删除
    map.remove("a");
}

上面用的是HashMap,前面的Hash翻译过来就是哈希的意思,是一种经典的map实现方法,除此之外还有另一种树结构的实现方式,对应于BTreeMap,它可以保持。

两者使用方法都是一样的,只不过底层实现方式不同而已,不过就我个人来说,大多数时候我还是喜欢使用HashMap

四、list

链表也是我们最常使用的一个集合了,其对于需要经常增、删的情形下效率比较高,这得益于其底层的实现细节,与之相对的就是数组,在rust中与之对应的就是Vec结构。

不过这些不是本文要讨论的东西,下面直接介绍其基本的使用方法:

use std::collections::LinkedList;
fn main() {
    let mut list = LinkedList::new();
    //添加元素(尾部)
    list.push_back("a1");
    //添加元素(头部)
    list.push_front("a2");
作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux