Rust语言入门教程(四) - 数据类型
标量类型(Scalar Types)
在Rust中,一共有4中标量类型, 也就是基本数据类型,分别是:
- 整型(Integers)
- 浮点型(Floats)
- 布尔型(Boolean)
- 字符型(Characters)
整型
| 无符号整型(Unsigned) | 有符号整型(Signed) |
|---|---|
| u8 | i8 |
| u16 | i16 |
| u32 | i32 |
| u64 | i64 |
| u128 | i128 |
| usize | isize |
其中分为无符号整型(以u开头),和有符号整型(以i开头),后面的数据代表该类型在内存中占多少bits. 其中usize类型是个例外,usize 类型的位数取决于目标平台的架构:
- 在 32 位架构上,
usize是 32 位的。 - 在 64 位架构上,
usize是 64 位的。
usize 类型通常用于索引集合和与内存大小相关的操作,其大小与平台的内存寻址能力相匹配,确保在任何平台上都能高效地进行这些操作。例如可以用于array或vector的索引的类型。isize与usize类似,只不过它是有符号的而已。
如果在声明一个整型变量时没有显式的标准类型的话,整型变量默认会被Rust识别为i32类型,因为这个类型的性能通常是最好的,即使是在64位的系统上也是如此。
需要注意的是,虽然Rust有这些整型,但根据你的系统位数不同,有的整型类型可能不被支持,比如在一个16-bit的系统中,就只支持16位及以下的整型类型(u8,i8, u16,i16)和usize, isize.
整型与进制
| 进制 | 写法示例 | 说明 |
|---|---|---|
| 十进制(Decimal) | 100000 | 直接以数字开头 |
| 十六进制(Hex) | 0xdeadbeef | 以0x开头的数字会被识别为16进制 |
| 八进制(Octal) | 0o77543211 | 以0o开头的数字会被识别为8进制 |
| 二进制(Binary) | 0b11110011 | 以0b开头的数字会被识别为二进制 |
| 字节(byte) | b’A’ | 用b开头,单引号内为一个ASCII码范围内的字符,因此byte类型在Rust中跟u8类型是等价的,因为他们都是0-255之间的数字 |
Rust会自动忽略在数字中出现的_, 因此可以在数字中间任意位置加上_以方便我们阅读代码,例如:
| 进制 | 写法示例 | 加下划线写法 |
|---|---|---|
| 十进制(Decimal) | 100000 | 100_000 |
| 十六进制(Hex) | 0xdeadbeef | 0xde_ad_be_ef |
| 八进制(Octal) | 0o77543211 | 0o7754_3211 |
| 二进制(Binary) | 0b11110011 | 0b1_1_1_1_0_0_1_1 |
浮点型
浮点类型比整型简单许多,只有两种类型:
- f32
- f64
他们之间的区别就是精度上的不同,默认情况下浮点数的类型是f64, 但是如果你的操作系统位数是低于64位的,f64的性能就会很差,这是需要注意的一点。
浮点类型的格式遵循IEEE-754标准规范,由整数位,小数点和小数位组成,如:
3.1415926 // legal
.1 // illegal, 必须有整数位
0.1 // legal
数字类型的声明方法
在定义一个数字类型的变量时, 有两种标注类型的方法。 第一种与我们之前介绍变量声明的章节中一样:
let x: u16 = 5;
let y: f32 = 3.14;
第二种方法,也可以将类型作为后缀,放在值的后面,如下:
let x = 5u16;
let y = 3.14f32;
为了方便阅读,也可以像在上一节中所说的一样,在数字中加上_, 如下:
let x = 5_u16;
let y = 3.14_f32;
这种方法在我们需要给一些泛型函数传递指定类型的参数时很有帮助, 比如一个函数有一个参数x, 这个参数x的类型可以是u16 , 也可以是u32, 根据参数的类型不同,函数的行为会发生变化, 此时如果我需要传入的参数值为5, 那么我就需要为这个5指定类型,那么便可以写为5u16 或者 5u32。
布尔型
布尔型只有两个可能的值:
- true
- false
注意都是小写。 可以如下定义一个布尔型变量:
let b: bool = true;
let c = false;
布尔型不是数字,因此不可以用于数学计算,除非用as关键词把它转换,例如:
fn main(){let x = 10 - true;println!("{}", x);
}
这样是会报错的, 但是改成下面这样就不会了:
fn main(){let x = 10 - true as u8;println!("{}", x);
}
上面的代码中true as u8会把布尔型转换成整型(1u8),因此最终程序输出的结果是9。
字符型
char这个类型的命名并不准确,每个char类型的变量应该都是一个标准的unicode值, 例如下面的值都是合法的:
let my_letter = 'a';
let i_kratkoa = 'й' ;
let ideograph = '你';
let my_fire = '🔥'
如上, 一个char变量的值可能是一个英文字母,也可能是一个其他语言中的字母,也可能是一个汉字, 甚至可以是一个表情符号,还可能是一些不可打印的控制符号,只要它是在unicode可以表示的范围内,一个char类型的变量占4 bytes的空间。
其他语言中, string一般都是由char组成的, 但是在Rust中却不是。Rust中的String中的元素是UTF-8格式的,而char类型不是, 因此String并没有用到char类型。
我们的代码编辑器显示的源代码也是UTF-8格式的,因此,我们在代码中看到的一个字符,其实并不等同于Rust中的一个char。
复合类型(Compound Types)
顾名思义, 复合类型就是把多个不同数据类型的值组合在一起,成为一个自定义的数据类型。
元组(Tuple)
我们要介绍的第一种复合类型是元组(tuple), 元组中可以存储多个不同类型的值,如下可以简单的声明并初始化一个元组:
let info = (1, 3.3, 999);
上面的元组中包含了3个数字,由于没有显式的标注变量类型, 根据我们前面的章节内容, 1 和 999 会被自动识别为 i32型, 3.3会被自动识别为f64型。如果要显式的标注元组类型,那么我们可以自然而然的想到应该像这样做:
let info: (u8, f64, i32) = (1, 3.3, 999);
元组操作
在Rust中想要访问元组中的元素有两种方式, 第一种是用.号, 通常也被叫做字段访问操作符, 例如:
let info: (u8, f64, i32) = (1, 3.3, 999);
let jets = info.0; // 1
let fuel = info.1; // 3.3
let ammo = info.2; // 999
我猜想Rust用.而不用[ ]来访问元组元素的原因,可能是为了暗示这样一个事实:元组成员的数据类型不一定是全部一样的。元组的字段是没有名称的,所以我们使用下标来访问元组成员, 和其他大多数编程语言一样, 元组的下标从0开始。
第二种访问元组成员的方法类似前面的章节中, 一次性为多个变量赋值,我们可以用一组与元组个数相同的变量直接解构一个元组,并将元组中的每个成员赋值给这些变量,如下:
let info: (u8, f64, i32) = (1, 3.3, 999);
// let jets = info.0; // 1
// let fuel = info.1; // 3.3
// let ammo = info.2; // 999
let (jets, fuel, ammo) = info;
元组长度限制
在Rust中,并没有严格规定元组的长度限制。然而,值得注意的是,Rust 标准库为长度最多为 12 的元组实现了某些特质,比如 Debug 和 Clone。这意味着如果你有一个长度超过 12 的元组,你可能需要为这个元组手动实现这些特质,或者使用不同的数据结构。
举个例子,对于一个有 13 个元素的元组 (T1, T2, T3, …, T13),你可能无法直接使用 println!(“{:?}”, tuple) 来打印这个元组,因为 Debug 特质默认只为长度最多为 12 的元组实现。这并不是说你不能创建长度超过 12 的元组,只是意味着某些元组操作可能不如较短元组那样开箱即用。
数组(Array)
与元组不同的是, 数组中存储的是一组相同类型的值。下面是一个声明并初始化数组的简单示例:
let buf = [1, 2, 3];
如果想要初始化一个所有元素都相同的数组,也可以通过这种形式来书写: [元素值; 元素个数], 例如:
let buf = [0; 3] // 等价于 let buf = [0, 0, 0];
标注数组的数据类型的方式跟元组不同,只能用[元素类型; 数组长度] 这样的格式, 下面给出了正确和错误的示例:
let buf: [u8; 3] = [1, 2, 3]; // 正确
let buf: [u8, u8, u8] = [1, 2, 3]; // 错误
对于数组元素的索引,我们就跟其他语言一样,使用[下标]的格式了,例如:
buf[0]
数组长度限制
在 Rust 中,数组长度最好不要超过 32。 跟元组的长度限制类似,这主要是因为 Rust 标准库中对数组实现了某些特质(traits)的自动派生(derive)仅限于长度最多为 32 的数组。这些特质包括常用的 Debug、Clone、Hash、PartialEq、Eq、PartialOrd、Ord 等。
对于长度超过 32 的数组,这些特质就不会自动实现。这意味着如果你有一个长度超过 32 的数组,例如 [i32; 33],你将无法使用 println!(“{:?}”, array) 来打印这个数组,因为 Debug 特质没有为这样的数组实现。同样,你也不能自动获得数组的克隆、比较等能力。
这个限制源于 Rust 标准库的设计决策,目的是平衡编译时间和可用性。由于 Rust 在编译时需要为每种数组长度和每个特质生成特定的实现代码,过长的数组会显著增加编译器的负担,尤其是在编译大型项目时。
因此,当你需要长度超过 32 的数组时,通常推荐使用向量(Vec),向量是一个动态数组,可以容纳任意数量的元素,并且不受上述特质实现的限制。向量提供了灵活性和扩展性,适合于需要动态大小或长度未知的情况。在性能敏感的场合,或者当数组大小在编译时已知且不会变化时,固定长度的数组(如 [T; N])才是更好的选择。
小结
本章主要介绍了Rust的四种标量类型的使用方法与注意事项,以及元组与数组的基本知识,下一章将介绍Rust中的流控制语句。
相关文章:
Rust语言入门教程(四) - 数据类型
标量类型(Scalar Types) 在Rust中,一共有4中标量类型, 也就是基本数据类型,分别是: 整型(Integers)浮点型(Floats)布尔型(Boolean)字符型(Chara…...
华为云人工智能入门级开发者认证学习笔记
人工智能入门级开发者认证 人工智能定义 定义 人工智能 (Artificial Intelligence) 是研究、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。 强人工智能 vs 弱人工智能 强人工智能:强人工智能观点认为有可能制造出真正能推理(…...
腾讯云发布新一代基于AMD处理器的星星海云服务器实例SA5
基础设施的硬实力,愈发成为云厂商的核心竞争力。 11月24日,腾讯云发布了全新一代星星海服务器。基于自研服务器的高密设计与硬件升级,对应云服务器SA5是全球首家搭载第四代AMD EPYC处理器(Bergamo)的公有云实例&#…...
算法通关村-----数论问题解析
最大公约数和最小公倍数 概念描述 最大公约数(GCD)是指两个或多个整数共有约数中的最大值。 最小公倍数(LCM)是指两个或多个整数共有的倍数中的最小值 方法介绍 碾转相除法 一种用于计算两个整数的最大公约数(GCD…...
wpf prism当中 发布订阅 IEventAggregator
先订阅后发布 private readonly IEventAggregator _eventAggregator; public LoginViewModel(ILoginService iloginService, IEventAggregator eventAggregator) {_iloginService iloginService;_eventAggregator eventAggregator;_eventAggregator.GetEvent<MessageEven…...
Angular中的getter函数
Angular 中的 getter 函数每次被调用时会返回一个新对象时,这些新对象并不使用同一个堆内存。详细解释一下: Getter 函数的作用是获取某个属性的值。在 Angular 中,getter 函数通常用于获取响应式数据(例如 Observables 或 Signal…...
Python----函数的数据 拆包(元组和字典)
Python拆包: 就是把元组或字典中的数据单独的拆分出来,然后赋予给其他的变量。 拆包: 对于函数中的多个返回数据, 去掉 元组, 列表 或者字典 直接获取里面数据的过程。 元组的拆包过程 def func():# 经过一系列操作返回一个元组return 100, 200 …...
vim翻页快捷键
Vim翻页 整页 Ctrlf向下翻页,下一页,相当于Page DownCtrlb向上翻页,上一页,相当于Page Up 半页 Ctrld向下半页,下一半页,光标下移Ctrlu向上半页,上衣半页,光标上移 按行 Ctrle…...
死锁是什么?死锁是如何产生的?如何破除死锁?
1. 死锁是什么 多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。 2. 死锁的三种典型情况 一个线程, 一把锁, 是不可重入锁, 该线程针对这个锁连续加锁两次, 就会出现死锁. 两个线程…...
给虚拟机配置静态id地址
1.令人头大的原因 当连接虚拟机的时候 地址不一会就改变,每次都要重新输入 2.配置虚拟机静态id地址 打开命令窗口执行 : vim /etc/sysconfig/network-scripts/ifcfg-ens33 按下面操作修改 查看自己子网掩码 3.重启网络 命令行输入 systemctl restart netwo…...
Mybatis-Plus 租户使用
Mybatis-Plus 租户使用 文章目录 Mybatis-Plus 租户使用一. 前言1.1 租户存在的意义1.2 租户框架 二. Mybatis-plus 租户2.1 租户处理器2.2 前置准备1. 依赖2. 表及数据准备3. 代码生成器 2.3 使用 三. 深入使用3.1 前言3.2 租户主体设值,取值3.3 部分表全量db操作3…...
vue el-table (固定列+滚动列)【横向滚动条】确定滚动条是在列头还是列尾
效果图: 代码实现: html: <script src"//unpkg.com/vue2/dist/vue.js"></script> <script src"//unpkg.com/element-ui2.15.14/lib/index.js"></script> <div id"app" style&quo…...
⑦【Redis GEO 】Redis常用数据类型:GEO [使用手册]
个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ Redis GEO ⑦Redis GEO 基本操作命令1.geoadd …...
LeetCode 2304. 网格中的最小路径代价:DP
【LetMeFly】2304.网格中的最小路径代价:DP 力扣题目链接:https://leetcode.cn/problems/minimum-path-cost-in-a-grid/ 给你一个下标从 0 开始的整数矩阵 grid ,矩阵大小为 m x n ,由从 0 到 m * n - 1 的不同整数组成。你可以…...
c 实用化的文本终端实时显示摄像头视频
因为采用yuv格式,帧率都很低。图像会拖影。把图像尺寸尽量缩小,能大大改善。现在最麻烦的是图像上有黑色的闪影,不知是为啥?如是framebuffer引起的就无解了。终于找到问题了,是在显示前加了一条用黑色清屏造成的&#…...
CSS中常用的伪类选择器
一 、伪类(不存在的类,特殊的类) -伪类用来描述一个元素的特殊状态 比如:第一个元素,被点击的元素,鼠标移入的元素 -特点:一般请情况下,使用:开头 1、 :first-child …...
【python学习】中级篇-数据库操作:SQLite
SQLite是一个轻量级的数据库引擎,它可以嵌入到各种应用程序中。以下是SQLite的基本用法: 创建数据库文件 import sqlite3# 连接到一个不存在的数据库文件,如果文件不存在,将会自动创建一个新的数据库文件 conn sqlite3.connect…...
汇编-PROTO声明过程
64位汇编 64 模式中,PROTO 伪指令指定程序的外部过程,示例如下: ExitProcess PROTO ;指定外部过程,不需要参数.code main PROCmov ebx, 0FFFFFFFFh mov ecx,0 ;结束程序call ExitProcess ;调用外部过程main ENDP END 32位…...
MYSQL事务操作
...
自动化测试——自动卸载软件
📢专注于分享软件测试干货内容,欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!📢交流讨论:欢迎加入我们一起学习!📢资源分享:耗时200小时精选的「软件测试」资…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
