【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中最最常用的两个容器的基本原理概述和使用方法和注意事项,后续会更新未说明的剩余的容器的使用方法和原理概述。

如有勘误,敬请指出。

相关推荐
Liquad Li5 小时前
Salesforce 主流认证方式、流程、适用场景
开发语言·salesforce
LOVE️YOU8 小时前
Python 中 Tuple 为什么有时可 Hash,有时不可 Hash?
开发语言·python·哈希算法
李永奉9 小时前
C语言-指针函数与函数指针及回调函数的使用
c语言·开发语言
小oo呆9 小时前
【学习心得】迭代器和可迭代对象
开发语言·python
AC赳赳老秦9 小时前
采集行为合规自检:OpenClaw 自动校验 robots 协议与采集频率,规避违规采集风险
java·开发语言·c++·python·php·deepseek·openclaw
钱栈up9 小时前
mvn compile 卡死在 javac 阶段:一次类型不匹配的排查与修复
java·开发语言
迅猛龙办公室9 小时前
Python输出当前计算机的系统日期和时间
开发语言·前端·python
杨丰玮4189 小时前
C语言基础知识(一)————各类符号的含义与输入输出库(stdio)
c语言·开发语言
程序猿编码10 小时前
工业视觉多任务方案:可编程梯度信息视觉框架,训练评估 + C++ 部署完整实战
开发语言·c++·视觉·推理引擎
言乐611 小时前
Python实现语音审核模型
开发语言·python·django·virtualenv·pygame