【Rust自学】3.3. 数据类型:复合类型

3.3.0. 写在正文之前

欢迎来到Rust自学的第三章,一共有6个小节,分别是:

  • 变量与可变性
  • 数据类型:标量类型
  • 数据类型:复合类型(本文)
  • 函数和注释
  • 控制流:if else
  • 控制流:循环

通过第二章的小游戏(没看的初学者强烈建议看一下),相信你已经学会了基本的Rust语法,而在第三章我们将更深一层,了解Rust中的通用的编程概念。

喜欢的话记得点赞、收藏加关注哦,想要跟着学下去记得关注专栏哦

3.3.1. 复合类型的简介

  • 复合类型可以将多个值放在一个类型里
  • Rust提供了两种基础的复合类型:元组(Tuple)、数组

3.3.1. 元组(Tuple)

元组的特点:

  • 元组可以将多个类型的多个值放在一个类型里
  • 元组的长度是固定的:一旦声明就无法改变

创建元组:

  • 在小括号里,将值用逗号分开
  • 元组中的每个位置都对应一个类型,元组中个元素的类型不必相同
rust 复制代码
fn main(){
	let tup:(u32,f32,i64) = (6657, 0.0721, 114514);
	println!("{},{},{}",tup.0,tup.1,tup.2);
	//Output: 6657,0.0721,114514
}

获取元组元素值:

  • 可以使用模式匹配来结构(destructure)一个元组来获取元素值。
rust 复制代码
fn main(){
	let let tup:(u32,f32,i64) = (6657, 0.0721, 114514);
	let (x, y, z) = tup;
	println!("{},{},{}", x, y, z);
	//Output: 6657,0.0721,114514
}

访问元组的元素:

  • 在元组变量后使用点标记法,后接元素的索引号
rust 复制代码
println!("{},{},{}", tup.0, tup.1, tup.2);

3.3.2. 数组

数组的特点:

  • 数组中的每个元素的类型必须相同
  • 数组也可以将多个值放入一个类型
  • 数组的长度是固定的

声明数组:

  • 在中括号里,各值用逗号分开
rust 复制代码
let a = [1, 1, 4, 5, 1, 4];

数组的用处:

  • 如果想把数组放在栈(Stack)上而不是堆(Heap)上,或者想保证有固定数量的元素,这时使用数组更有好处。
  • 数组没有Vector灵活(以后会讲)。
    • Vector和数组类似,它由标准库;数组由prelude模块(也是标准库的一部分)提供。
    • Vector的长度可以改变
    • 不确定应该使用数组还是Vector时,大概率应该使用Vector。

数组的类型:

  • 数组的类型以[类型;长度]的形式表示
rust 复制代码
let machine:[u32,4] = [6, 6, 5, 7];

声明数组的其他方法:

  • 如果数组的每个元素值都相同,那么可以:
    • 在中括号里指定初始值
    • 然后跟着一个;
    • 最后加上数组的长度
rust 复制代码
let a = [3;2];
let b = [3, 3, 3];

这个例子中ab的写法是等价的。

访问数组的元素:

  • 数组是Stack上分配的的单个块的内存
  • 可以使用索引来访问数组的元素
rust 复制代码
let machine = [6, 6, 5, 7];
let wjq = machine[0];
  • 如果访问的索引超出了数组的范围:
    • cargo build时会报错,cargo check时不会
    • 运行时会报错,因为Rust不会允许其继续访问相应地址的内存。

数组的原理是一块连续的内存,假设数组的第一个元素在内存上的x位置,那么第二个元素的位置就是x加第一个元素的长度,之后的以此类推。

如果索引值超过了数组的实际长度,那么程序就会读取不在数组位置的其他内存位置,而这个地方的值不一定是什么。在C中完全没有边界检查。在C++中普通数组没有,只有std::array有;在Rust里强制边界检查

特性 C C++ Rust
内存模型 连续 连续 连续
安全性 无边界检查 std::array有边界检查,普通数组无 强制边界检查
动态数组支持 需要手动管理内存 std::vector Vec
多维数组支持
特殊能力 简单高效 STL容器丰富 所有权和借用检查

但Rust只会对数组进行简单的边界检查,如果将代码写的稍微复杂一点,Rust就无法在编译时检查,只能在运行时进行检查。

rust 复制代码
let a = 5;
let machine = [6, 6, 5, 7];
let wjq = machine[a];

这个代码Rust会在编译时报错

rust 复制代码
let a = [1, 9, 10, 4, 5];
let machine = [6, 6, 5, 7];
let wjq = machine[a[4]];

这个代码Rust就不会在编译时报错,但在运行时会报错

相关推荐
鹿鹿的布丁12 分钟前
通过Lua脚本多个网关循环外呼
后端
墨子白12 分钟前
application.yml 文件必须配置哇
后端
xcya19 分钟前
Java ReentrantLock 核心用法
后端
用户4665370150531 分钟前
如何在 IntelliJ IDEA 中可视化压缩提交到生产分支
后端·github
小楓120137 分钟前
MySQL數據庫開發教學(一) 基本架構
数据库·后端·mysql
天天摸鱼的java工程师40 分钟前
Java 解析 JSON 文件:八年老开发的实战总结(从业务到代码)
java·后端·面试
白仑色41 分钟前
Spring Boot 全局异常处理
java·spring boot·后端·全局异常处理·统一返回格式
之诺1 小时前
MySQL通信过程字符集转换
后端·mysql
喵手1 小时前
反射机制:你真的了解它的“能力”吗?
java·后端·java ee
用户466537015051 小时前
git代码压缩合并
后端·github