Rust中vector的详细用法

 更新时间:2024年03月14日 11:30:02   作者:ftzchina  
Rust和C++同样也有vector概念,本文主要介绍了Rust中vector的详细用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

用过C++的相信对vector概念不陌生了,C++中我们称vector为容器,它能够像容器一样存放各种类型的对象。Rust中同样也有vector概念,在Rust中vector 允许我们在一个单独的数据结构中储存多个值,所有值在内存中彼此相邻排列,在内存中的存储形式和数组一样,vector 只能储存相同类型的值。但是借助另一种结构(枚举),我们可以用vector存储不同类型的值,当然这是包了一层,下面我们讲一下Rust的vector详细用法。

一:vector的实例创建

fn main() {
    let vec_ins:Vec<u32> = Vec::new();
}

上面我们通过Vec的new函数创建了一个vector实例,并指定了其里面存储的值是u32类型,那我们用new创建的时候能不能不指定值类型呢。

这是不允许的,如果用new创建的时候不指定类型,那么因为没有向这个 vector 中插入任何值,Rust 并不知道我们想要储存什么类型的元素。这一点非常重要。vector 是用泛型实现的,第 10 章会涉及到如何对你自己的类型使用它们。现在,我们知道 Vec 是一个由标准库提供的类型,它可以存放任何类型,而当 Vec 存放某个特定类型时,那个类型位于尖括号中。        

那假如我在创建的同时,传入vector的元素,是不是就意味着不用显示的指定类型。

fn main() {
    let vec_ins = vec![1, 2, 3];
    println!("vec is {:?}",vec_ins); 
}

运行结果:

PS F:\skillup\rust\hello_world\greeting> cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.03s
     Running `target\debug\greeting.exe`
vec is [1, 2, 3]

vector创建的同时传入了元素,Rust 就可以根据插入的元素推断出存放的类型。更常见的做法是使用初始值来创建一个 Vec,而且为了方便 Rust 提供了 vec! 宏。这个宏会根据我们提供的值来创建一个新的 Vec。

二:vector的元素插入

我们创建了vector,那么如何向vector中插入元素。

fn main() {
    let mut vec_ins:Vec<char> = Vec::new();
    vec_ins.push('f');
    vec_ins.push('t');
    vec_ins.push('z');
    println!("vec is {:?}",vec_ins); 
}

运行结果:

PS F:\skillup\rust\hello_world\greeting> cargo run
   Compiling greeting v0.1.0 (F:\skillup\rust\hello_world\greeting)
    Finished dev [unoptimized + debuginfo] target(s) in 1.19s
     Running `target\debug\greeting.exe`
vec is ['f', 't', 'z']

Rust中可以使用 push 方法往vector中插入元素

三:vector的元素读取

在Rust中我们有两种方法来获取vector中元素的值,一是通过索引,二是通过get方法。下面我们来看一个具体的例子

fn main() {
    let mut vec_ins:Vec<char> = Vec::new();
    vec_ins.push('f');
    vec_ins.push('t');
    vec_ins.push('z');
    println!("vec is {:?}",vec_ins); 

    let second_ele= vec_ins[1];
    println!("the second element is {}",second_ele); 

    match vec_ins.get(1) {
        Some(second_ele) => println!("The second element is {}", second_ele),
        None => println!("There is no second element."),
    }
}

运行结果:

S F:\skillup\rust\hello_world\greeting> cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.03s
     Running `target\debug\greeting.exe`
vec is ['f', 't', 'z']
the second element is t
The second element is t

Rust 有两个引用元素的方法的原因是程序可以选择如何处理当索引值在 vector 中没有对应值的情况。

当引用一个不存在的元素时 Rust 会造成 panic。这个方法更适合当程序认为尝试访问超过 vector 结尾的元素是一个严重错误的情况,这时应该使程序崩溃。比如vector总共有5个元素,你用下标去获取第6个元素,就是越界访问,这时候程序就panic了,当 get 方法被传递了一个数组外的索引时,它不会 panic 而是返回 None。当偶尔出现超过 vector 范围的访问属于正常情况的时候可以考虑使用它。接着你的代码可以有处理 Some(&element) 或 None 的逻辑。例如,索引可能来源于用户输入的数字。如果它们不慎输入了一个过大的数字那么程序就会得到 None 值,你可以告诉用户当前 vector 元素的数量并再请求它们输入一个有效的值。这就比因为输入错误而使程序崩溃要友好的多!

一旦程序获取了一个有效的引用,借用检查器将会执行所有权和借用规则来确保 vector 内容的这个引用和任何其他引用保持有效。不能在相同作用域中同时存在可变和不可变引用的规则。当我们获取了 vector 的第一个元素的不可变引用并尝试在 vector 末尾增加一个元素的时候,这是行不通的:

fn main() {
    let mut v = vec![1, 2, 3, 4, 5];

    let first = &v[0];

    v.push(6);

    println!("The first element is: {}", first);
}

为什么第一个元素的引用会关心 vector 结尾的变化?不能这么做的原因是由于 vector 的工作方式:在 vector 的结尾增加新元素时,在没有足够空间将所有所有元素依次相邻存放的情况下,可能会要求分配新内存并将老的元素拷贝到新的空间中。这时,第一个元素的引用就指向了被释放的内存。借用规则阻止程序陷入这种状况。

四:vector的元素遍历

 我们可以用for循环来遍历vector元素

fn main() {
    let mut vec_ins:Vec<char> = Vec::new();
    vec_ins.push('f');
    vec_ins.push('t');
    vec_ins.push('z');
    println!("vec is {:?}",vec_ins); 

    for i in &vec_ins{
        println!("the element is {}",i);
    }
}

运行结果:

vec is ['f', 't', 'z']
the element is f
the element is t
the element is z

那么我们能不能遍历的同时改变vector元素的值呢

fn main() {
    let mut vec_ins:Vec<char> = Vec::new();
    vec_ins.push('f');
    vec_ins.push('t');
    vec_ins.push('z');
    println!("vec is {:?}",vec_ins); 

    for i in &mut vec_ins{
        *i = 'x'
    }
    println!("the element is {:?}",vec_ins);
}

运行结果:

vec is ['f', 't', 'z']
the element is ['x', 'x', 'x']

为了修改可变引用所指向的值,在使用 = 运算符之前必须使用解引用运算符(*)获取 i 中的值

五:vector借助枚举来存储不同类型的值

上面讲到vector 只能储存相同类型的值。如果有这个限制vector说实话和数组功能就相差无几了。何谓道高一尺,魔高一丈,很幸运的是vector绝对有能力做到存储不同类型的值,不过要借助另外一个结构,枚举的成员都被定义为相同的枚举类型,所以当需要在 vector 中储存不同类型值时,我们可以定义并使用一个枚举!

#[derive(Debug)]
enum Student {
    Age(i32),
    Sex(char),
    Name(String),
}
fn main() {
    let student = vec![
        Student::Age(18),
        Student::Sex('男'),
        Student::Name(String::from("ftz"))
    ];
    println!("The student is {:?}",student);
}

上面我们借助枚举来存储一个学生的信息,包括年龄,性别,名字,对应三种不同的数据类型。

六:vector学习总结

Rust 在编译时就必须准确的知道 vector 中类型的原因在于它需要知道储存每个元素到底需要多少内存。第二个好处是可以准确的知道这个 vector 中允许什么类型。如果 Rust 允许 vector 存放任意类型,那么当对 vector 元素执行操作时一个或多个类型的值就有可能会造成错误。使用枚举外加 match 意味着 Rust 能在编译时就保证总是会处理所有可能的情况。

到此这篇关于Rust中vector的详细用法的文章就介绍到这了,更多相关Rust vector内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Rust 语言中的 into() 方法及代码实例

    Rust 语言中的 into() 方法及代码实例

    在 Rust 中,into() 方法通常用于将一个类型的值转换为另一个类型,这通常涉及到资源的所有权转移,本文给大家介绍Rust 语言中的 into() 方法及代码实例,感谢的朋友跟随小编一起看看吧
    2024-03-03
  • Rust中用enum实现多参数Hook机制完整代码

    Rust中用enum实现多参数Hook机制完整代码

    在 Rust 中,如果想为enum实现一个带多参数的 Hook 机制,可以结合模式匹配和枚举来处理,这种方式可以扩展到支持不同类型的输入参数和逻辑处理,下面通过示例代码介绍Rust中用enum实现多参数Hook机制,感兴趣的朋友一起看看吧
    2024-12-12
  • 一文详解Rust中的错误处理

    一文详解Rust中的错误处理

    这篇文章主要为大家详细介绍了Rust中的错误处理的相关知识,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • Rust 中 Mutex 的基本用法

    Rust 中 Mutex 的基本用法

    Rust 标准库中的 Mutex 结构体位于 std::sync::Mutex 中,它提供了线程安全的数据访问,Mutex 保证了在同一时间只有一个线程可以访问被锁定的数据,这篇文章主要介绍了Rust 中 Mutex 的基本用法,需要的朋友可以参考下
    2024-05-05
  • Rust生命周期常见误区(中英对照)全面指南

    Rust生命周期常见误区(中英对照)全面指南

    这篇文章主要WEIDJAI 介绍了Rust生命周期常见误区(中英对照)的全面指南,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • 一文学会Rust语言如何操作JSON

    一文学会Rust语言如何操作JSON

    JSON在Web开发中被广泛应用于数据交换,本文主要介绍了Rust语言操作JSON,包括序列化、反序列化、JSON创建等多个方面,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Rust利用tauri制作个效率小工具

    Rust利用tauri制作个效率小工具

    日常使用电脑中经常会用到一个quicke工具中的轮盘菜单工具。但quicke免费版很多功能不支持,且它的触发逻辑用的不舒服,经常误触。所以本文就来用tauri自制一个小工具,希望对大家有所帮助
    2023-02-02
  • Rust使用csv crate构建CSV文件读取器的全过程

    Rust使用csv crate构建CSV文件读取器的全过程

    这篇文章主要学习如何基于Rust使用csv这个crate构建一个CSV文件读取器的过程,学习了csv相关的用法以及一些往期学过的crate的复习,兼顾了实用性和Rust的学习,需要的朋友可以参考下
    2024-05-05
  • Rust中的Drop特性之解读自动化资源清理的魔法

    Rust中的Drop特性之解读自动化资源清理的魔法

    Rust通过Drop特性实现了自动清理机制,确保资源在对象超出作用域时自动释放,避免了手动管理资源时可能出现的内存泄漏或双重释放问题,智能指针如Box、Rc和RefCell都依赖于Drop来管理资源,提供了灵活且安全的资源管理方案
    2025-02-02
  • 深入了解Rust 结构体的使用

    深入了解Rust 结构体的使用

    结构体是一种自定义的数据类型,它允许我们将多个不同的类型组合成一个整体。下面我们就来学习如何定义和使用结构体,并对比元组与结构体之间的异同,需要的可以参考一下
    2022-11-11

最新评论