Rust语言入门教程(四) - 数据类型

标量类型(Scalar Types)

在Rust中,一共有4中标量类型, 也就是基本数据类型,分别是:

  • 整型(Integers)
  • 浮点型(Floats)
  • 布尔型(Boolean)
  • 字符型(Characters)

整型

无符号整型(Unsigned)有符号整型(Signed)
u8i8
u16i16
u32i32
u64i64
u128i128
usizeisize

其中分为无符号整型(以u开头),和有符号整型(以i开头),后面的数据代表该类型在内存中占多少bits. 其中usize类型是个例外,usize 类型的位数取决于目标平台的架构:

  • 在 32 位架构上,usize 是 32 位的。
  • 在 64 位架构上,usize 是 64 位的。

usize 类型通常用于索引集合和与内存大小相关的操作,其大小与平台的内存寻址能力相匹配,确保在任何平台上都能高效地进行这些操作。例如可以用于arrayvector的索引的类型。isizeusize类似,只不过它是有符号的而已。

如果在声明一个整型变量时没有显式的标准类型的话,整型变量默认会被Rust识别为i32类型,因为这个类型的性能通常是最好的,即使是在64位的系统上也是如此。

需要注意的是,虽然Rust有这些整型,但根据你的系统位数不同,有的整型类型可能不被支持,比如在一个16-bit的系统中,就只支持16位及以下的整型类型(u8,i8, u16,i16)和usize, isize.

整型与进制

进制写法示例说明
十进制(Decimal)100000直接以数字开头
十六进制(Hex)0xdeadbeef0x开头的数字会被识别为16进制
八进制(Octal)0o775432110o开头的数字会被识别为8进制
二进制(Binary)0b111100110b开头的数字会被识别为二进制
字节(byte)b’A’用b开头,单引号内为一个ASCII码范围内的字符,因此byte类型在Rust中跟u8类型是等价的,因为他们都是0-255之间的数字

Rust会自动忽略在数字中出现的_, 因此可以在数字中间任意位置加上_以方便我们阅读代码,例如:

进制写法示例加下划线写法
十进制(Decimal)100000100_000
十六进制(Hex)0xdeadbeef0xde_ad_be_ef
八进制(Octal)0o775432110o7754_3211
二进制(Binary)0b111100110b1_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个数字,由于没有显式的标注变量类型, 根据我们前面的章节内容, 1999 会被自动识别为 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中的流控制语句。

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

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

相关文章

深信服实验学习笔记——nmap常用命令

文章目录 1. 主机存活探测2. 常见端口扫描、服务版本探测、服务器版本识别3. 全端口&#xff08;TCP/UDP&#xff09;扫描4. 最详细的端口扫描5. 三种TCP扫描方式 1. 主机存活探测 nmap -sP <靶机IP>-sP代表 2. 常见端口扫描、服务版本探测、服务器版本识别 推荐加上-v参…

DNS/ICMP协议、NAT技术

目录 DNS协议DNS背景域名简介 ICMP协议ICMP功能ping命令traceroute命令 NAT技术NAT技术背景NAT IP转换过程NAPTNAT技术的缺陷NAT和代理服务器 网络协议总结应用层传输层网络层数据链路层 DNS协议 DNS&#xff08;Domain Name System&#xff0c;域名系统&#xff09;协议&…

基于51单片机的公交自动报站系统

**单片机设计介绍&#xff0c; 基于51单片机的公交自动报站系统 文章目录 一 概要公交自动报站系统概述工作原理应用与优势 二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 很高兴为您介绍基于51单片机的公交自动报站系统&#xff1a; 公交自动报…

吉他初学者学习网站搭建系列(1)——目录

文章目录 背景文章目录功能网站地址网站展示展望 背景 这个系列是对我最近周末搭建的吉他工具类平台YUERGS的总结。我个人业余爱好是自学吉他&#xff0c;我会在这个平台中动手集成我认为很有帮助的一些工具&#xff0c;来提升我的吉他水平和音乐素养&#xff0c;希望也可以帮…

【Linux】指令详解(三)

目录 1. 前言2. 常见指令2.1 重定向2.1.1 >2.1.2 >>2.1.3 < 2.2 与文件有关指令2.2.1 more2.2.2 less &#xff08;推荐使用&#xff09;2.2.3 head2.2.4 tail2.2.5 wc2.2.6 | 2.3 find2.4 grep 3. 时间相关的指令3.1 data3.2 时间戳3.3 cal 4. zip/unzip 1. 前言 …

rsyslog学习

rsyslog是什么 RSYSLOG&#xff08;Remote System Logging&#xff09;是一个开源的日志处理工具&#xff0c;用于在 Linux 和 Unix 系统上收集、处理和转发日志。它是一个健壮且高性能的日志处理程序&#xff0c;可以替换 Syslogd 作为标准的系统日志程序。RSYSLOG 提供了许多…

力扣学习笔记——239. 滑动窗口最大值

力扣学习笔记——239. 滑动窗口最大值 题目描述 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1&#xff1a; 输…

vue-router的使用技巧

一、安装 npm install vue-router 二、引入 main.ts引入 import { createApp } from vue import App from ./App.vue import router from ./routerconst app createApp(App)app.use(router) app.mount(#app)三、定义路由文件 路由的参数 meta添加路由的其他参数 redire…

第96步 深度学习图像目标检测:FCOS建模

基于WIN10的64位系统演示 一、写在前面 本期开始&#xff0c;我们继续学习深度学习图像目标检测系列&#xff0c;FCOS&#xff08;Fully Convolutional One-Stage Object Detection&#xff09;模型。 二、FCOS简介 FCOS&#xff08;Fully Convolutional One-Stage Object D…

Javaweb之Vue组件库Element的详细解析

4 Vue组件库Element 4.1 Element介绍 不知道同学们还否记得我们之前讲解的前端开发模式MVVM&#xff0c;我们之前学习的vue是侧重于VM开发的&#xff0c;主要用于数据绑定到视图的&#xff0c;那么接下来我们学习的ElementUI就是一款侧重于V开发的前端框架&#xff0c;主要用…

两年功能五年自动化测试面试经验分享

最近有机会做一些面试工作&#xff0c;主要负责面试软件测试人员招聘的技术面试。 之前一直是应聘者的角色&#xff0c;经历了不少次的面试之后&#xff0c;多少也积累一点面试的经验&#xff0c;现在发生了角色转变。初次的面试就碰到个工作年限比我长的&#xff0c;也没有时…

【数据结构实验】排序(一)冒泡排序改进算法 Bubble及其性能分析

文章目录 1. 引言2. 冒泡排序算法原理2.1 传统冒泡排序2.2 改进的冒泡排序 3. 实验内容3.1 实验题目&#xff08;一&#xff09;输入要求&#xff08;二&#xff09;输出要求 3.2 算法实现 4. 实验结果5. 实验结论 1. 引言 排序算法是计算机科学中一个重要而基础的研究领域&…

AndroidStudio2022.3.1 Patch3使用国内下载源加速

记录一下这个版本的as在使用国内下载源加速碰到的诸多问题。 一、gradle-8.0-bin.zip下载慢 编辑项目文件夹/gradle/wrapper/gradle-wrapper.properties&#xff0c;文件内容改为如下&#xff1a; #Fri Nov 24 18:50:06 CST 2023 distributionBaseGRADLE_USER_HOME distribu…

井盖位移传感器怎么监测井盖安全

井盖在城市基础设施建设中扮演着不可或缺的角色&#xff0c;虽然看似并不起眼但确实是城市规划中一个重要的组成部分。在城市规划建设之初都需要首先考虑排水系统的设计&#xff0c;而井盖作为排水系统的一个重要组成部分&#xff0c;一旦出现问题便会造成交通中断或者环境受影…

CSS-元素的分类与特性

块元素&#xff08;block&#xff09; 又称&#xff1a;块级元素 特点&#xff1a; 在页面中独占一行&#xff0c;不会与任何元素共用一行&#xff0c;是从上到下排列的默认宽度&#xff1a;撑满父元素默认高度&#xff1a;由内容撑开可以通过 CSS 设置宽高 人话&#xff1a;宽…

天线的负载

在电磁学和通信工程领域&#xff0c;天线的负载&#xff08;Load&#xff09;通常指连接到天线的部分或元件&#xff0c;该部分在电学上对天线的输入产生影响。天线的负载可以是被连接到天线的阻抗元件、电感、电容、电阻或其他电性元件。 具体而言&#xff0c;天线的负载是指…

【电源专题】在DC/DC电源电感下方铺铜的利弊?

对 DC/DC 电源的电感底部是否应该铺铜这个问题,硬件工程师们常常意见分歧。 一种观点认为,在电感下方铺铜会在接地面上产生涡流;涡流会影响功率电感的电感量并增加系统损耗,而接地面噪声会影响其他高速信号。 另一种观点则认为,完整的铜平面可以降低 EMI 并改善散热特性。…

递归方法来计算二叉树的双分支节点个数

1.递归方法来计算二叉树的双分支节点个数 首先&#xff0c;你需要定义二叉树的节点结构&#xff0c;然后编写递归函数 #include <stdio.h> #include <stdlib.h>// 定义二叉树的节点结构 struct TreeNode {int value;struct TreeNode* left;struct TreeNode* righ…

1panel可视化Docker面板安装与使用

官网地址1Panel - 现代化、开源的 Linux 服务器运维管理面板 文章目录 目录 文章目录 前言 一、环境准备 二、使用步骤 1.安装命令 2.一些命令 3.使用 总结 前言 一、环境准备 虚拟机centos 已经安装好docker和 Docker Compose 或者都没安装 1panel会帮你自动安装 二、使用…

【腾讯云云上实验室】向量数据库相亲社交应用实践

快速入口 &#x1f449;向量数据库_大模型知识库_向量数据存储_向量数据检索- 腾讯云 (tencent.com) 文章目录 前言1. 向量数据库概念及原理1.1 向量数据库概念1.2 向量数据库核心原理1.3 向量数据库优缺点1.4 向量数据库与传统数据库的区别 2. 腾讯云向量数据库的基本特性及优…