【Rust中的容器(一)】

Rust中的容器


前言

容器即将一系列具有相同特征的数据存储在一起。在编程过程中,开发者使用到的容器种类、原理以及使用方式基本相同。

Rust最常用的两个容器:

  1. Vector
  2. HashMap

Rust中其他的容器:

双端队列:VecDeque

链表:LinkedList

映射:BtreeMap

集合:HashSet,BtreeSet

其他:BinaryHeap


Vector原理以及使用方法

Rust中的Vector和C++中的Vector基本一致,都可以动态扩展,都是二倍增加,都是紧密排列,都可以指定容量,非常适合在不确定数据量大小时候使用。

与之对应的是array,与C++并无二致,在声明期需要确定大小,且使用期间不可变,适合固定大小的数据,如月份等。
特点在于,rust中的vector必然要遵守rust的所有权规则

  1. 与在rust中的其他的变量一致,当数组nums超出作用域之后,将被回收。
    代码示例:
rust 复制代码
{
	let nums = vec![1,1,1];
}
println!("{:?}", nums); //将会报错,因为nums已经超出作用域
  1. rust中读取数组中的元素方式,与C++类似,既支持了index访问形式,也支持了方法访问,C++使用at(index),Rust使用get(index),不同的是at如果超出了C++动态数组的大小,会抛出异常Out of Range ,而Get方法在Rust中会返回一个Option值 ,更安全的交给开发者做出反应。所以index适合开发者完全确认不会越界的情况下使用,而get(),适合避免越界的情况下使用。
    代码示例:
rust 复制代码
fn main() {
    let nums = vec![1, 3, 2, 4, 5];
    let second = &nums[1];
    println!("{second}");
    let first = nums.get(0);
    match first {
        Some(vfirst) => println!("{}", vfirst),
        None => println!("nothing found"),
    }
}
  1. 代码示例:
rust 复制代码
fn main() {
    let mut nums = vec![1, 2, 3, 4, 5];
    let num = &nums[1];
    nums.push(6);
    println!("{num}");
}

Rust中的借用和引用一章中,提到过在同一作用域下,可变不可变不能同时出现。结合上述代码,问题会出现在:

rust 复制代码
	nums.push(6); 
    println!("{num}");

也就是动态数组中的元素在可变引用后使用了不可变引用,将会报错:
cannot borrow nums as mutable because it is also borrowed as immutable

如此严格的原因正是由于rust的安全性,vector是可以扩展的,当push后vector扩展后将会发生内存地址变化,原来不可变引用便会失效。

  1. 有关数组的排序,初始化等不在赘述,这里有个比较重要的点需要举例说明。在泛型与特征对象中我们提到过,当特征trait作为函数返回值时,返回值无法返回不同类型的对象Rust的泛型与特征,由此展开了特征对象的概念(形如Box),使用vector时我们一般也不会仅仅存储简单类型,而是根据需求存储,具有同类特征的类型对象便是非常常用的存储方式。
    代码示例:
rust 复制代码
trait Name {
    fn name(&self);
}

struct Dog {
    name: String,
}
struct Cat {
    name: String,
}

impl Name for Dog {
    fn name(&self) {
        println!("The dog's name is: {}", self.name);
    }
}
impl Name for Cat {
    fn name(&self) {
        println!("The cat's name is: {}", self.name);
    }
}
fn main() {
    let animalvec: Vec<Box<dyn Name>> = vec![
        Box::new(Dog {
            name: "Rex".to_string(),
        }),
        Box::new(Cat {
            name: "Whiskers".to_string(),
        }),
        Box::new(Dog {
            name: "Buddy".to_string(),
        }),
    ];

    for animal in &animalvec {
        animal.name();
    }
}

HashMap原理以及使用方法

Hashmap在其他语言中也及其常见和常被使用,都是使用hashtable存储键值对,并通过链式存储解决hash冲突,查找速度极快O(1).

常用操作: 创建,插入,删除,查找

代码示例:

rust 复制代码
use std::collections::HashMap;
fn main() {
    let mut mymap = HashMap::new();//创建
    mymap.insert(1, "cat");//插入
    mymap.insert(2, "dog");
    mymap.insert(3, "fish");
    mymap.remove(&2);//删除
    let cat = mymap[&1];//查询
    println!("{cat}");
    println!("{:?}", mymap); // Output: {2: "cat", 3: "fish"}
    mymap.insert(3, "Dog");//原值更新
    println!("{:?}", mymap); // Output: {2: "dog", 3: "cat"}
}

总结

上述是Rust中最最常用的两个容器的基本原理概述和使用方法和注意事项,后续会更新未说明的剩余的容器的使用方法和原理概述。

如有勘误,敬请指出。

相关推荐
St_Ludwig几秒前
C语言 蓝桥杯某例题解决方案(查找完数)
c语言·c++·后端·算法·游戏·蓝桥杯
松树戈6 分钟前
JS推荐实践
开发语言·javascript·ecmascript
瑞雨溪9 分钟前
java中的this关键字
java·开发语言
vener_13 分钟前
LuckySheet协同编辑后端示例(Django+Channel,Websocket通信)
javascript·后端·python·websocket·django·luckysheet
MapleLea1f32 分钟前
26届JAVA 学习日记——Day14
java·开发语言·学习·tcp/ip·程序人生·学习方法
小汤猿人类33 分钟前
SpringTask
开发语言·python
计算机毕设孵化场39 分钟前
计算机毕设-基于springboot的多彩吉安红色旅游网站的设计与实现(附源码+lw+ppt+开题报告)
vue.js·spring boot·后端·计算机外设·课程设计·计算机毕设论文·多彩吉安红色旅游网站
爪哇学长40 分钟前
解锁API的无限潜力:RESTful、SOAP、GraphQL和Webhooks的应用前景
java·开发语言·后端·restful·graphql
老赵的博客1 小时前
QT 自定义界面布局要诀
开发语言·qt
p-knowledge1 小时前
建造者模式(Builder Pattern)
java·开发语言·建造者模式