【零基础学Rust | 基础系列 | 数据结构】元组,数组,向量,字符串,结构体

在这里插入图片描述


文章标题

  • 简介:
  • 一,元组:
    • 1,定义元组:
    • 2,访问元组元素:
    • 3,元组解构:
    • 4,元组在函数中的应用:
  • 二,数组:
    • 1,数组的声明和初始化
    • 2,访问数组元素
    • 3,数组的遍历
    • 4,数组的长度
    • 5,数组和函数
  • 三,向量:
    • 1,创建向量:
    • 2,访问向量:
    • 3,修改向量:
    • 4,遍历向量:
    • 5,常用方法:
  • 四,字符串:
    • 1,创建字符串:
    • 2,更新字符串:
    • 3,字符串连接:
    • 4,访问字符串内容:
    • 5,字符串切片:
    • 6,字符串和其他类型的转换:
  • 五,结构体:
    • 1,定义结构体
    • 2,创建结构体实例
    • 3,访问结构体字段
    • 4,修改结构体字段
    • 5,结构体更新语法
    • 6,元组结构体
    • 7,单元结构体
    • 8,结构体所有权
  • 总结:


简介:

在Rust编程语言中,数据结构是组织和存储数据的一种方式,它们使得数据可以高效地被访问和操作。本章将详细介绍元组,数组,向量,字符串,和结构体这几种基本的数据结构。

一,元组:

元组是Rust编程语言中的一种复合数据类型,它可以包含多个值,这些值可以是不同类型。元组的大小是固定的,一旦定义,其长度和元素的类型就不能改变。

1,定义元组:

在Rust中,元组是通过圆括号(())来定义的,元素之间用逗号(,)分隔。每个元素可以是不同类型,元组的类型是由所有元素的类型共同决定的。例如,下面的代码定义了一个包含三个元素的元组,第一个元素是整数,第二个元素是浮点数,第三个元素是字符串。

let tup: (i32, f64, &str) = (500, 6.4, "hello");

2,访问元组元素:

在元组中,可以使用点号(.)后跟索引来访问元素。索引是从0开始的,所以第一个元素的索引是0,第二个元素的索引是1,以此类推。例如,下面的代码分别获取了元组tup的第一个,第二个,和第三个元素。

let five_hundred = tup.0;
let six_point_four = tup.1;
let hello = tup.2;

3,元组解构:

除了使用索引访问元组元素外,Rust还提供了一种称为“解构”的方式来访问元组元素。解构是一种将元组的元素分解到不同的变量中的操作。例如,下面的代码将元组tup的元素解构到了三个变量x,y,和z中。

let (x, y, z) = tup;

在这段代码执行后,变量x的值是500,变量y的值是6.4,变量z的值是"hello"。

4,元组在函数中的应用:

在Rust中,函数可以返回元组,这使得函数可以返回多个值。例如,下面的函数返回一个包含两个元素的元组,第一个元素是输入的两个数的和,第二个元素是输入的两个数的差。

fn add_and_sub(a: i32, b: i32) -> (i32, i32) {(a + b, a - b)
}

调用这个函数时,可以使用解构来获取返回的元组的元素。

let (sum, diff) = add_and_sub(5, 3);

在这段代码执行后,变量sum的值是8,变量diff的值是2。


二,数组:

在Rust编程语言中,数组是一种基本的数据结构,用于存储多个相同类型的元素。数组的长度在声明时就已经确定,且在后续的使用中不能更改。这种固定长度的特性使得数组在某些场景下非常有用,例如,当你需要在栈上而不是在堆上存储数据时,或者当你需要确保总是有固定数量的元素时。

1,数组的声明和初始化

在Rust中,数组的声明和初始化可以通过多种方式完成。最基本的方式是使用方括号,其中包含了每个元素的类型和数组的长度,然后是等号,后面跟着用逗号分隔的元素列表。例如,以下代码声明并初始化了一个包含五个整数的数组:

let a: [i32; 5] = [1, 2, 3, 4, 5];

如果你想要创建一个每个元素都是相同值的数组,Rust提供了一个简洁的语法:首先是元素类型,然后是分号,然后是数组的长度,然后是等号,最后是元素的值。例如,以下代码创建了一个包含五个零的数组:

let a = [0; 5];

2,访问数组元素

在Rust中,可以使用索引来访问数组的元素。索引是在方括号中指定的数字,表示要访问的元素的位置。注意,数组的索引从0开始,所以第一个元素的索引是0,第二个元素的索引是1,以此类推。例如,以下代码创建了一个数组,并访问了其第一个和第二个元素:

let a = [1, 2, 3, 4, 5];
let first = a[0];
let second = a[1];

如果你尝试访问超出数组长度的索引,Rust会在编译时报错。这是Rust的一种安全性保护机制,可以防止访问无效的内存。

3,数组的遍历

遍历数组是一种常见的操作,可以用于访问和操作数组中的每个元素。在Rust中,可以使用for循环来遍历数组。例如,以下代码创建了一个数组,并打印了每个元素:

let a = [1, 2, 3, 4, 5];
for element in &a {println!("{}", element);
}

注意,这里使用了&a而不是a来获取数组的引用。这是因为在for循环中,Rust默认会获取元素的所有权,如果你不想改变数组的所有权,就需要使用引用。

4,数组的长度

可以使用.len()方法来获取数组的长度。例如,以下代码创建了一个数组,并打印了其长度:

let a = [1, 2, 3, 4, 5];
println!("{}", a.len());

5,数组和函数

在Rust中,可以将数组作为函数的参数,或者将数组作为函数的返回值。当将数组作为函数的参数时,需要指定数组的长度。例如,以下代码定义了一个函数,该函数接受一个包含五个整数的数组,并返回数组中的第一个元素:

fn first_element(a: [i32; 5]) -> i32 {a[0]
}
let a = [1, 2, 3, 4, 5];
println!("{}", first_element(a));

三,向量:

向量(Vector)是Rust的一种基本数据类型,它是一种可增长和缩小的数组。向量在内存中是连续的,可以高效地访问和修改。

1,创建向量:

创建向量的最常见方式是使用Vec::new函数,这将创建一个新的,空的向量。

let v: Vec<i32> = Vec::new();

也可以使用vec!宏来创建一个包含初始值的向量。

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

2,访问向量:

可以使用索引来访问向量中的值。注意,索引从0开始。

let v = vec![1, 2, 3];
let second = v[1];

也可以使用get方法来访问向量中的值,这将返回一个Option。如果索引在向量的范围内,get方法将返回Some,否则返回None

let v = vec![1, 2, 3];
let second = v.get(1);

3,修改向量:

可以使用push方法向向量的末尾添加元素。

let mut v = vec![1, 2, 3];
v.push(4);

也可以使用pop方法移除并返回向量的最后一个元素。

let mut v = vec![1, 2, 3];
let last = v.pop();

4,遍历向量:

可以使用for循环来遍历向量中的所有元素。

let v = vec![1, 2, 3];
for i in &v {println!("{}", i);
}

如果需要在遍历向量的同时修改元素,可以使用iter_mut方法。

let mut v = vec![1, 2, 3];
for i in v.iter_mut() {*i += 1;
}

5,常用方法:

向量有许多其他的方法,例如len方法可以返回向量的长度,is_empty方法可以检查向量是否为空,clear方法可以清空向量,insert方法可以在指定位置插入元素,remove方法可以移除指定位置的元素,等等。

let mut v = vec![1, 2, 3];
println!("{}", v.len()); // 输出:3
println!("{}", v.is_empty()); // 输出:false
v.clear();
println!("{}", v.is_empty()); // 输出:true

四,字符串:

字符串是编程中最常见的数据类型之一,它们是字符的序列。在Rust中,字符串被设计为UTF-8编码,这意味着它们可以包含任何正确的UTF-8序列。Rust的字符串处理功能强大且灵活,但也有一些复杂性。

1,创建字符串:

在Rust中,可以使用多种方式创建字符串。最常见的方式是使用String::from函数,这将创建一个String类型的字符串。

let s = String::from("hello");

另一种方式是直接使用字符串字面量创建字符串,这将创建一个&str类型的字符串。

let s = "hello";

2,更新字符串:

Rust的String类型的字符串是可变的,可以使用push_strpush方法添加内容。

let mut s = String::from("hello");
s.push_str(", world"); // push_str方法接受字符串切片
s.push('!'); // push方法接受单个字符

3,字符串连接:

Rust提供了多种方式来连接字符串。最直接的方式是使用+运算符或format!宏。

let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2; // 注意s1被移动了,不能再被使用let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = format!("{}{}", s1, s2); // s1和s2都没有被移动,可以继续使用

4,访问字符串内容:

由于Rust字符串是UTF-8编码的,所以不能简单地使用索引来访问单个字符。但是,可以使用迭代器来遍历字符串的每个字符。

let s = String::from("hello, world!");
for c in s.chars() {println!("{}", c);
}

5,字符串切片:

字符串切片是字符串的一部分,它的类型是&str。可以使用范围来创建字符串切片。

let s = String::from("hello, world!");
let hello = &s[0..5];
let world = &s[7..12];

6,字符串和其他类型的转换:

可以使用parse方法将字符串转换为其他类型,例如整数和浮点数。同样,也可以使用to_string方法将其他类型转换为字符串。

let s = "42";
let n: i32 = s.parse().unwrap();let n = 42;
let s = n.to_string();

五,结构体:

结构体(Struct)是Rust中的一种自定义数据类型,允许将多个相关的值,可能是不同类型的,组合在一起。结构体在Rust编程中非常重要,它们可以用来创建复杂的数据类型,以更好地模拟现实世界的对象和概念。

1,定义结构体

定义结构体需要使用struct关键字,后跟结构体的名称和一对大括号。在大括号内部,可以定义任意数量的字段,每个字段都需要有一个名称和一个类型。

struct Point {x: i32,y: i32,
}

在这个例子中,定义了一个名为Point的结构体,它有两个字段:xy,都是i32类型。

2,创建结构体实例

创建结构体实例需要使用结构体的名称,后跟一对大括号。在大括号内部,需要为每个字段提供一个值。

let p = Point { x: 0, y: 0 };

在这个例子中,创建了一个Point的实例p,并为xy字段分别赋值为0

3,访问结构体字段

访问结构体字段需要使用结构体实例的名称,后跟一个点号(.)和字段的名称。

let x = p.x;
let y = p.y;

在这个例子中,访问了pxy字段,并将它们的值分别赋给了xy变量。

4,修改结构体字段

如果需要修改结构体字段的值,需要首先将结构体实例声明为可变的。然后,可以使用结构体实例的名称,后跟一个点号(.)和字段的名称,来修改字段的值。

let mut p = Point { x: 0, y: 0 };
p.x = 5;
p.y = 10;

在这个例子中,首先创建了一个可变的Point实例p,然后修改了xy字段的值。

5,结构体更新语法

当需要创建一个新的结构体实例,且部分字段的值与已有实例相同时,可以使用结构体更新语法。这需要使用两个点号(…)后跟已有实例的名称。

let p1 = Point { x: 0, y: 0 };
let p2 = Point { x: 5, ..p1 };

在这个例子中,创建了一个新的Point实例p2,它的x字段的值为5y字段的值与p1y字段的值相同。

6,元组结构体

元组结构体是一种特殊的结构体,它的字段没有名称,只有类型。元组结构体的名称后跟一对小括号,小括号内部是字段的类型。

struct Color(i32, i32, i32);let white = Color(255, 255, 255);

在这个例子中,定义了一个名为Color的元组结构体,它有三个i32类型的字段。然后,创建了一个Color的实例white

7,单元结构体

单元结构体是一种特殊的结构体,它没有任何字段。单元结构体的名称后跟一个分号。

struct Unit;let u = Unit;

在这个例子中,定义了一个名为Unit的单元结构体。然后,创建了一个Unit的实例u

8,结构体所有权

结构体可以拥有其他类型的所有权。例如,可以在结构体中包含字符串类型的字段。

struct User {username: String,email: String,
}let user = User {username: String::from("user1"),email: String::from("user1@example.com"),
};

在这个例子中,定义了一个名为User的结构体,它有两个String类型的字段:usernameemail。然后,创建了一个User的实例user

结构体是Rust中的一种重要的数据结构,它可以用来创建复杂的数据类型,以更好地模拟现实世界的对象和概念。

总结:

本章详细介绍了Rust中的几种基本数据结构:元组,数组,向量,字符串,和结构体。这些数据结构在Rust编程中非常重要,理解和掌握它们是学习Rust的关键步骤。希望通过本章的学习,读者能够对这些数据结构有一个深入的理解,并能在实际编程中灵活运用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/55859.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人工智能与物理学(软体机器人能量角度)的结合思考

前言 好久没有更新我的CSDN博客了&#xff0c;细细数下来已经有了16个月。在本科时期我主要研究嵌入式&#xff0c;研究生阶段对人工智能感兴趣&#xff0c;看了一些这方面的论文和视频&#xff0c;因此用博客记录了一下&#xff0c;后来因为要搞自己的研究方向&#xff0c;就…

Docker 启动 Nacos 报错:No DataSource set

​ &#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 …

一款开源免费、更符合现代用户需求的论坛系统:vanilla

对于个人建站来说&#xff0c;WordPress相信很多读者都知道了。但WordPress很多时候我们还是用来建立自主发布内容的站点为主&#xff0c;适用于个人博客、企业主站等。虽然有的主题可以把WordPress变为论坛&#xff0c;但效果并不是很好。 所以&#xff0c;今天给大家推荐一个…

基于图像形态学处理的目标几何形状检测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 .................................................... %二进制化图像 Images_bin imbinari…

大数据技术之Clickhouse---入门篇---SQL操作、副本

星光下的赶路人star的个人主页 积一勺以成江河&#xff0c;累微尘以崇峻极 文章目录 1、SQL操作1.1 Insert1.2 Update 和 Delete1.3 查询操作1.4 alter操作1.5 导出数据 2、副本2.1 副本写入流程2.2 配置步骤 1、SQL操作 基本上来说传统关系型数据库&#xff08;以 MySQL 为例…

TiDB 源码编译之 PD/TiDB Dashboard 篇

作者&#xff1a; ShawnYan 原文来源&#xff1a; https://tidb.net/blog/a16b1d46 TiDB TiDB 是 PingCAP 公司自主设计、研发的开源分布式关系型数据库&#xff0c;是一款同时支持在线事务处理与在线分析处理 (Hybrid Transactional and Analytical Processing, HTAP) 的融…

使用C#的窗体显示与隐藏动画效果方案 - 开源研究系列文章

今天继续研究C#的WinForm的显示动画效果。 上次我们实现了无边框窗体的显示动画效果(见博文&#xff1a;基于C#的无边框窗体动画效果的完美解决方案 - 开源研究系列文章 )&#xff0c;这次介绍的是未在任务栏托盘中窗体的显示隐藏动画效果的实现代码。 1、 项目目录&#xff1b…

unity TextMeshPro 富文本

<b>粗体标签</b> <i>斜体标签</i> <u>下划线标签</u> <s>删除线标签</s> <sup>上标标签</sup>前面后边上标签 5<sup>。</sup>C <sub>下标标签&#xff0c;如&#xff1a;</sub>H<sub&…

解决Win11右键菜单问题

✅作者简介&#xff1a;大家好&#xff0c;我是Cisyam&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Cisyam-Shark的博客 &#x1f49e;当前专栏&#xff1a; 程序日常 ✨特色专栏&…

MyBatis源码剖析之Mapper代理方式细节

MyBatis是一个流行的Java持久层框架&#xff0c;它提供了多种方式来执行数据库操作&#xff0c;其中之一就是通过Mapper代理方式。通过Mapper代理方式&#xff0c;开发者可以编写接口&#xff0c;然后MyBatis会动态地生成接口的实现类&#xff0c;从而避免了繁琐的SQL映射配置。…

无涯教程-Perl - chop函数

描述 此函数从EXPR,LIST的每个元素或$_(如果未指定值)中删除最后一个字符。 语法 以下是此函数的简单语法- chop VARIABLEchop( LIST )chop返回值 此函数返回从EXPR中删除的字符,并且在列表context中,从LIST的最后一个元素中删除该字符。 例 以下是显示其基本用法的示例…

Vue2 第十七节 Vue中的Ajax

1.Vue脚手架配置代理 2.vue-resource 一.Vue脚手架配置代理 1.1 使用Ajax库 -- axios ① 安装 : npm i axios ② 引入: import axios from axios ③ 使用示例 1.2 解决开发环境Ajax跨域问题 跨域&#xff1a;违背了同源策略&#xff0c;同源策略规定协议名&#xff0…