【零基础学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的关键步骤。希望通过本章的学习,读者能够对这些数据结构有一个深入的理解,并能在实际编程中灵活运用。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

GG修改器安装与Root环境的安装

关于GG修改器大家应该都有一定的了解吧&#xff0c;就是类似于电脑端CE的一个软件。 GG修改器在百度云盘里请自行下载&#xff01; 百度网盘链接&#xff1a;https://pan.baidu.com/s/1p3KJRg9oq4s0XzRuEIBH4Q 提取码&#xff1a;vuwj 那我要开始了&#xff01; 本来不想讲GG…

【状态估计】一维粒子滤波研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

一条自由游动的鲸鱼

先看效果&#xff1a; 再看代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>鲸鱼</title><style>#canvas-container {width: 100%;height: 100vh;overflow: hidden;}&l…

策略模式:优雅地实现可扩展的设计

策略模式&#xff1a;优雅地实现可扩展的设计 摘要&#xff1a; 策略模式是一种常用的设计模式&#xff0c;它可以帮助我们实现可扩展的、灵活的代码结构。本文将通过一个计算器案例来介绍策略模式的概念、使用场景以及如何在实际项目中应用策略模式来提高代码的可维护性和可扩…

[C++项目] Boost文档 站内搜索引擎(1): 项目背景介绍、相关技术栈、相关概念介绍...

项目背景 Boost库是C中一个非常重要的开源库. 它实现了许多C标准库中没有涉及的特性和功能, 一度成为了C标准库的拓展库. C新标准的内容, 很大一部分脱胎于Boost库中. Boost库的高质量代码 以及 提供了更多实用方便的C组件, 使得Boost库在C开发中会被高频使用 为方便开发者学…

设计模式行为型——备忘录模式

目录 什么是备忘录模式 备忘录模式的实现 备忘录模式角色 备忘录模式类图 备忘录模式举例 备忘录模式代码实现 备忘录模式的特点 优点 缺点 使用场景 注意事项 实际应用 什么是备忘录模式 备忘录模式&#xff08;Memento Pattern&#xff09;又叫做快照模式&#x…

qt源码---事件系统之QCoreApplication

上一节分析了qt和windows系统之间的消息的传递&#xff0c;本节着重看一下&#xff0c;qt内部的事件是如何传递的&#xff1f; 1.sendEvent函数 在使用的自定义事件时&#xff0c;有时需要手动抛出一个事件&#xff0c;常用的方式有2种&#xff0c;其一时阻塞式的sendEvent函…

在IDEA同一个窗口中同时打开多个独立项目

文章说明 本文主要说明如何在Intellij Idea中同时打开多个独立的Maven项目。 我在使用idea的时候&#xff0c;由于自己负责了很多项目&#xff0c;经常要在不通的代码之间切换来切换去。然后搜索代码的时候也只能搜到当前打开的这个项目。因为这个原因&#xff0c;一些小项目…

wxwidgets Ribbon使用wxRibbonToolBar实例

wxRibbonToolBar就是工具栏&#xff0c;一下是实现的效果&#xff0c;界面只是功能展示&#xff0c;没有美化 实现代码如下所示&#xff1a; MyFrame::MyFrame(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(800, 600)) …

vue中点击添加类名,并且实现升降序

1.介绍 要求&#xff1a;掌握indexOf()用法&#xff1b;动态绑定类名的对象写法&#xff1b;iconfont使用&#xff1b;split()用法&#xff1b;三元运算符用法&#xff1b;es6模板字符串&#xff1b; 说明&#xff1a;首先综合元素默认有元素并且是降序。服务器传来的数据格式…

C++物理引擎Box2D的下载,编译,VS2013配置环境

文章目录 网站和下载地址编译工具:编译box2dhelloworld测试网站和下载地址 https://box2d.org/ 下载地址 https://hub.nuaa.cf/erincatto/box2d/tags 编译工具: 1.VS2013 2.cmake 下载地址 https://cmake.org/ 编译box2d 下载box2d源码2.4.0,解压。在box2d-2.4.0目录下…

什么是场景营销,小红书场景营销方式和方法有哪些

现在小红书上最流行的就是场景营销&#xff0c;那什么是场景营销&#xff0c;应该怎么做呢&#xff1f;今天来和大家分享下大家都在说得场景营销是什么&#xff0c;在小红书投放怎么做好场景营销&#xff1f; 一、什么是场景化营销 说白来&#xff0c;场景营销(Scene Marketing…

机器学习深度学习——从全连接层到卷积

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——非NVIDIA显卡怎么做深度学习&#xff08;坑点排查&#xff09; &#x1f4da;订阅专栏&#xff1a;机器…

Python测试框架pytest:测试用例、查找子集、参数化、跳过

Pytest是一个基于python的测试框架&#xff0c;用于编写和执行测试代码。pytest主要用于API测试&#xff0c;可以编写代码来测试API、数据库、UI等。 pytest是一个非常成熟的全功能的Python测试框架&#xff0c;主要有以下几个优点&#xff1a; 简单灵活&#xff0c;容易上手。…

react搭建在线编辑html的站点——引入grapes实现在线拖拉拽编辑html

文章目录 ⭐前言⭐搭建react ts项目⭐引入grapes 插件⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于react搭建在线编辑html的站点。 react 发展历史 React是由Facebook开发的一种JavaScript库&#xff0c;用于构建用户界面。React最初发布于2013年&…

没有配置redis但是报错连接redis失败

问题 没有配置redis但是报错连接redis失败 检查maven配置是否引入了redis依赖&#xff08;可能是传递依赖&#xff0c;最好检查引进来的公共工程 解决办法 只需要在该工程application.yml文件中配置一下 redis就好&#xff0c;或者移除redis依赖 spring:redis:password: hos…

一文了解 Android Auto 车载开发~

作者&#xff1a;牛蛙点点申请出战 背景 我的的产品作为一个海外音乐播放器&#xff0c;在车载场景听歌是一个很普遍的需求。在用户反馈中&#xff0c;也有很多用户提到希望能在车上播放音乐。同时车载音乐也可以作为提升用户消费时长一个抓手。 出海产品&#xff0c;主要服务…

【Vue】Parsing error: No Babel config file detected for ... vue

报错 Parsing error: No Babel config file detected for E:\Study\Vue网站\实现防篡改的水印\demo02\src\App.vue. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files.             …

玩机搞机---安卓新机型payload.bin刷写救砖 无需专用线刷包

目前的新机型官方卡刷包解包后都是payload.bin分区格式的卡刷固件。而有个别一些机型没有线刷包&#xff0c;当这些机型出现系统问题的时候有以下几种方法参考救砖。遇到类似故障的朋友可以借鉴参考下. 其中的不足和相关的资源可以参考这两个博文。任何教程的目的只是拓展你的…

反射调用private方法的坑

使用反射调用私有方法时&#xff0c;发现空指针异常&#xff0c;无法直接注入导致空指针异常 加入如下代码后&#xff0c;恢复正常 if (AopUtils.isCglibProxy(marketSmsTaskService)) {// 如果是cglib代理对象&#xff0c;则转为原始对象marketSmsTaskService (MarketSmsTas…