Rust - 数据类型

Rust 是静态编译语言,在编译时必须知道所有变量的类型。

基于使用的值,编译器通常能推断出它的具体类型,但如果可能的类型比较多,例如把String转换为整数的parse方法,就必须添加类型的标注,否则编译会报错。

//报错:程序不知道把字符串转换成啥类型
let guess = "42".parse().expect("Not a number");
//正确:程序知道要转换成u32类型
let guess:u32 = "42".parse().expect("Not a number");

在rust中,每个值都有其确切的数据类型,总的来说可以分为两类:标量类型和复合类型。

一个标量类型意味着它代表的是一个单个的值,rust有三个主要的标量类型:

  • 数值类型: 有符号整数 (i8, i16, i32, i64, isize)、 无符号整数 (u8, u16, u32, u64, usize) 、浮点数 (f32, f64)
  • 布尔类型: true和false
  • 字符类型: 表示单个 Unicode 字符,存储为 4 个字节

复合类型,顾名思义,是指由多个标量类型的值和其他符号组合而成的数据类型

Rust内置的复合类型有:元组、数组。

一、标量类型

(一)整数类型

比如 i32 类型(rust默认的整数值类型),表示的就是有符号的 32 位整数类型( i 是英文单词 integer 的首字母,与之相反的是 u,代表无符号 unsigned 类型)。下表显示了 Rust 中的内置的整数类型:

长度(视架构而定)有符号类型无符号类型
8 位i8u8
16 位i16u16
32 位i32u32
64 位i64u64
arch(架构位数,如128)isize(i128)usize(u128)

类型定义的形式统一为:有无符号 + 类型大小(位数)。无符号数表示数字只能取正数和0,而有符号则表示数字可以取正数、负数还有0。就像在纸上写数字一样:当要强调符号时,数字前面可以带上正号或负号;然而,当很明显确定数字为正数时,就不需要加上正号了。有符号数字以补码形式存储。

每个有符号类型规定的数字范围是 -(2n - 1) ~ 2n - 1 - 1,其中 n 是该定义形式的位长度。因此 i8 可存储数字范围是 -(27) ~ 27 - 1,即 -128 ~ 127。无符号类型可以存储的数字范围是 0 ~ 2n - 1,所以 u8 能够存储的数字为 0 ~ 28 - 1,即 0 ~ 255。

整数溢出

例如:u8的范围是0-255,如果你把一个u8变量的值设为256,那么

  1. 在调试模式下:rust会检查整数溢出,如果发生溢出,程序在运行时会报错。
  2. 在发布模式下(–release):rust不会检查可能导致报错的整数溢出。如果溢出发生,会执行“环绕”操作,就像一个钟表一样转圈,将256变成0,257变成1…以此类推,且不会报错。

(二)浮点类型

浮点类型数字 是带有小数点的数字,在 Rust 中浮点类型数字也有两种基本类型: f32 和 f64,分别为 32 位和 64 位大小。默认浮点类型是 f64,在现代的 CPU 中它的速度与 f32 几乎相同,但精度更高。

下面是一个演示浮点数的示例:

fn main() {let x = 2.0; // f64let y: f32 = 3.0; // f32
}

浮点数根据 IEEE-754 标准实现。f32 类型是单精度浮点型,f64 为双精度。

(三)字符类型

Rust 的 char 类型是语言中最原生的字母类型。下面是一些声明 char 值的例子:

fn main() {let c = 'z';let z: char = 'ℤ';let g = '国';let heart_eyed_cat = '😻';
}

Rust 的字符不仅仅是 ASCII,所有的 Unicode 值都可以作为 Rust 字符,包括单个的中文、日文、韩文、emoji 表情符号等等,都是合法的字符类型。Unicode 值的范围从 U+0000 ~ U+D7FF 和 U+E000 ~ U+10FFFF。

由于 Unicode 都是 4 个字节编码,因此字符类型也是占用 4 个字节。

(四)布尔类型

正如其他大部分编程语言一样,Rust 中的布尔类型有两个可能的值:true 和 false。Rust 中的布尔类型使用 bool 表示,且布尔值占用内存的大小为 1 个字节:

fn main() {let t = true;let f: bool = false; // 使用类型标注,显式指定f的类型if f {println!("这是段毫无意义的代码");}
}

使用布尔类型的场景主要在于流程控制,例如上述代码的中的 if 就是其中之一。

二、复合类型

复合类型可以将多个值放在一个类型里。

Rust提供了两种基础的复合类型:元组、数组。

(一)元组

元组是一个将多个其他类型的值组合进一个复合类型的主要方式。元组长度固定,一旦声明结束,其长度不会增大或缩小。

我们在小括号里,将值用逗号分开来表示创建一个元组。元组中的每一个位置都有一个类型,而且这些不同值的类型也不必是相同的。如下表示创建一个元组:

fn main() {let tup: (i32, f64, u8) = (500, 6.4, 1);
}//let 元组变量名:(类型1, 类型2, 类型3) = (值1, 值2, 值3);

变量 tup 被绑定了一个元组值 (500, 6.4, 1),该元组的类型是 (i32, f64, u8)。

所以元组就是用括号将多个类型组合到一起。

可以使用模式匹配或者 . 操作符来获取元组中的值。

用模式匹配解构元组
fn main() {let tup = (500, 6.4, 1);let (x, y, z) = tup;println!("The value of y is: {}", y);
}

上述代码首先创建一个元组,然后将其绑定到 tup 上,接着使用 let (x, y, z) = tup; 来完成一次模式匹配,因为元组是 (n1, n2, n3) 形式的,因此我们用一模一样的 (x, y, z) 形式来进行匹配,元组中对应的值会绑定到变量 x, y, z上。这就是解构:用同样的形式把一个复杂对象中的值匹配出来。

用.来访问元组

模式匹配可以让我们一次性把元组中的值全部或者部分获取出来,如果只想要访问某个特定元素,那模式匹配就略显繁琐,对此,Rust 提供了 . 的访问方式:

fn main() {let x: (i32, f64, u8) = (500, 6.4, 1);let five_hundred = x.0;let six_point_four = x.1;let one = x.2;
}

和其它语言的数组、字符串一样,元组的索引从 0 开始。

(二)数组

另一个包含多个值的方式是 数组array)。

与元组不同,数组中的每个元素的类型必须相同。Rust 中的数组与一些其他语言中的数组不同,Rust 中的数组长度是固定的。

在 Rust 中,数组是这样定义的:

fn main() {let a = [1, 2, 3, 4, 5];
}

数组语法跟 JavaScript 很像,也跟大多数编程语言很像。由于它的元素类型大小固定,且长度也是固定,因此数组 array 是存储在栈上,性能也会非常优秀。

但是数组却没有动态数组(Vector)灵活。vector 类型是标准库提供的一个 允许 增长和缩小长度的类似数组的集合类型,我们称为“动态数组”。动态数组 Vector 是存储在堆上,因此长度可以动态改变。当你不确定是使用数组还是动态数组时,那就应该使用后者。

举个例子,在需要知道一年中各个月份名称的程序中,你很可能希望使用的是数组而不是动态数组。因为月份是固定的,它总是只包含 12 个元素:

let months = ["January", "February", "March", "April", "May", "June", "July","August", "September", "October", "November", "December"];

在一些时候,还需要为数组声明类型,如下所示:

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

这里,数组类型是通过方括号语法声明,i32 是元素类型,分号后面的数字 5 是数组长度,数组类型也从侧面说明了数组的元素类型要统一,长度要固定

还可以使用下面的语法初始化一个某个值重复出现 N 次的数组

let a = [3; 5];
// let a = [3,3,3,3,3]

a 数组包含 5 个元素,这些元素的初始化值为 3,不难发现,这种语法跟数组类型的声明语法其实是保持一致的:[3; 5] 和 [类型; 长度]。在元素重复的场景,这种写法要简单的多。

访问数组元素

因为数组是Stack上分配的单个块内存,元素的存放顺序是连续的,因此可以通过索引的方式来访问存放其中的元素:

fn main() {let a = [9, 8, 7, 6, 5];let first = a[0]; // 获取a数组第一个元素let second = a[1]; // 获取第二个元素
}

与许多语言类似,数组的索引下标是从 0 开始的。此处,first 获取到的值是 9,second 是 8。

如果访问的索引超出了数组的范围,那么就会引发越界访问错误。

如果是显性的越界访问错误,那么rust就会在编译时及时阻止我们:

fn main() {let a = [9, 8, 7, 6, 5];let s = a[5];println!("{}",s);
}
// let s = a[5]; index out of bounds: the length is 5 but the index is 5

如果是隐性的越界访问错误,那么rust编译会通过,但运行时程序会崩溃报错:

use std::io;fn main() {let a = [1, 2, 3, 4, 5];println!("Please enter an array index.");let mut index = String::new();// 读取控制台的输出io::stdin().read_line(&mut index).expect("Failed to read line");//读取到的字符串转为无符号整型数字let index: usize = index.trim().parse().expect("Index entered was not a number");//索引访问let element = a[index];println!("The value of the element at index {} is: {}",index, element);
}

使用 cargo run 来运行代码,因为数组只有 5 个元素,如果我们试图输入 5 去访问第 6 个元素,则会访问到不存在的数组元素,最终程序会崩溃退出。

这就是数组访问越界,访问了数组中不存在的元素,导致 Rust 运行时错误。程序因此退出并显示错误消息,未执行最后的 println! 语句。

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

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

相关文章

JVM字节码与类的加载——类的加载过程详解

文章目录 1、概述2、加载(Loading)阶段2.1、加载完成的操作2.2、二进制流的获取方式2.3、类模型与Class实例的位置2.4、数组类的加载 3、链接(Linking)阶段3.1、链接阶段之验证(Verification)3.1.1、格式检查3.1.2、字节码的语义检查3.1.3、字节码验证3.1.4、符号引用验证 3.2、…

Harmony鸿蒙南向驱动开发-I3C

I3C(Improved Inter Integrated Circuit)总线是由MIPI Alliance开发的一种简单、低成本的双向二线制同步串行总线。 I3C是两线双向串行总线,针对多个传感器从设备进行了优化,并且一次只能由一个I3C主设备控制。相比于I2C&#xf…

langchain LCEL,prompt模块,outputparse输出模块

目录 基本代码 prompt模块 prompt模版控制长度 outputparse格式化输出 LangChain表达式语言,或者LCEL,是一种声明式的方式,可以轻松地将链条组合在一起 langchian 可以使用 通义千问,我们用通义千问,用法也要申请…

Stream流中方法详解

中间方法和终结方法 以下传入参数均表示lambda表达式中的参数 forEach():遍历集合,对流中的每个元素执行指定的操作 ArrayList<String> list new ArrayList<>(Arrays.asList("a","b","c","d")); list.stream().forEac…

基于ros的相机内参标定过程

基于ros的相机内参标定过程 1. 安装还对应相机的驱动2. 启动相机节点发布主题3. 下载camera_calibartion4. 将红框的文件夹复制在自己的工作空间里边&#xff0c;编译5. 标定完成以后&#xff0c;生成内参参数文件camera.yaml。将文件放在对应的路径下&#xff0c;修改config文…

ArcGIS Server 10发布要素服务时遇到的数据库注册问题总结(一)

工作环境&#xff1a; Windows 7 64 位旗舰版 ArcGIS Server 10.1 ArcGIS Desktop 10.1 IIS 7.0 开始的时候以为10.1发布要素服务和10.0一样&#xff0c;需要安装ArcSDE&#xff0c;后来查阅资料发现不需要&#xff0c;数据库直连方式就可以了。 首先我来说一下发布要素服…

stm32开发之threadx+netxduo(tcp 服务端使用记录)

前言 本篇需要用到threadx之动态内存的实现记录 里面的动态内存分配管理代码.开发环境使用的stm32cubemxclion组合芯片使用的是stm32f407zgt6,网口使用的是lan8720&#xff0c;使用cubemx提供的lan8742也可以驱动&#xff0c;注意实际的网口与芯片的引脚 示例代码 tcp 服务端…

关于可视化大屏适配

一、目前市场上适配方案有两种&#xff1b; vw、vh方案&#xff1a; 原理&#xff1a;按照设计稿的尺寸&#xff0c;将px按比例计算转为vw和vh&#xff1b; 优点&#xff1a;不会存在失真情况、可以动态计算图表的宽高&#xff0c;字体等&#xff0c;灵活性较高&#xff0c;…

国内SSL证书应用情况如何?

随着互联网的快速发展&#xff0c;越来越多的网站开始意识到数据安全的重要性&#xff0c;并开始使用SSL证书来保护网站和用户的数据安全。在国内&#xff0c;SSL证书的应用也逐渐得到推广和普及。本文将介绍国内SSL证书的应用情况。 首先&#xff0c;国内许多大型电商平台和金…

Excel文本内容抽取工具[Python]

#创作灵感# 一堆Excel文件&#xff0c;每个打开看太累了。写个脚本直接显示里面的内容多好。最好这些内容可以直接复制到剪切板&#xff0c;方便以后编辑修改。只需要将文件拖动到全屏置顶的文本框内&#xff0c;就能弹出Excel里的内容。支持一次选取多个文件。 开干&#xff…

计算机视觉——引导APSF和梯度自适应卷积增强夜间雾霾图像的可见性算法与模型部署(C++/python)

摘要 在夜间雾霾场景中&#xff0c;可见性经常受到低光照、强烈光晕、光散射以及多色光源等多种因素的影响而降低。现有的夜间除雾方法常常难以处理光晕或低光照条件&#xff0c;导致视觉效果过暗或光晕效应无法被有效抑制。本文通过抑制光晕和增强低光区域来提升单张夜间雾霾…

N1922A是德科技N1922A功率传感器

181/2461/8938产品概述&#xff1a; N192XA 传感器是首款通过将直流参考源和开关电路集成到功率传感器中来提供内部调零和校准的传感器。此功能消除了与使用外部校准源相关的多个连接&#xff0c;从而最大限度地减少了连接器磨损、测试时间和测量不确定性。 连接到 DUT 时进行…

从零开始精通RTSP之请求与响应详解1

概述 RTSP是一种基于文本的应用层协议&#xff0c;使用UTF-8编码&#xff0c;并通过TCP或UDP传输。它并不直接传输媒体数据&#xff0c;而是用于控制媒体数据的传输&#xff0c;比如&#xff1a;播放、暂停、快进等操作。RTSP客户端通过发送请求到服务器&#xff0c;服务器则响…

【kears】(01)keras使用介绍

文章目录 一.特点二.keras如何支持TensorFlow、CNTK 和 Theano2.1 使用 TensorFlow 后端引擎训练和评估模型2.2 使用 TensorFlow 后端引擎训练和评估模型2.3 使用 Theano后端引擎训练和评估模型2.4 不同深度学习框架如何选择1.1 keras.datasets&#xff1a;包含多种常用数据集1…

InsectMamba:基于状态空间模型的害虫分类

InsectMamba&#xff1a;基于状态空间模型的害虫分类 摘要IntroductionRelated WorkImage ClassificationInsect Pest Classification PreliminariesInsectMambaOverall Architecture InsectMamba: Insect Pest Classification with State Space Model 摘要 害虫分类是农业技术…

Excel从零基础到高手【办公】

第1课 - 快速制作目录【上篇】第1课 - 快速制作目录【下篇】第2课 - 快速定位到工作表的天涯海角第3课 - 如何最大化显示工作表的界面第4课 - 给你的表格做个瘦身第5课 - 快速定位目标区域所在位置第6课 - 快速批量填充序号第7课 - 按自定义的序列排序第8课 - 快速删除空白行第…

C++数据结构与算法——贪心算法难题

C第二阶段——数据结构和算法&#xff0c;之前学过一点点数据结构&#xff0c;当时是基于Python来学习的&#xff0c;现在基于C查漏补缺&#xff0c;尤其是树的部分。这一部分计划一个月&#xff0c;主要利用代码随想录来学习&#xff0c;刷题使用力扣网站&#xff0c;不定时更…

计算机视觉异常检测——PatchCore面向全召回率的工业异常检测

1. 概述 异常检测问题在工业图像数据分析中扮演着至关重要的角色&#xff0c;其目的是从大量正常数据中识别出异常行为或模式。这一任务的挑战在于&#xff0c;正常数据的样本相对容易获取&#xff0c;而异常情况却因其稀有性和多样性而难以收集。为了解决这一问题&#xff0c…

跟TED演讲学英文:Why AI will spark exponential economic growth by Cathie Wood

TED英文文稿 文章目录 TED英文文稿Why AI will spark exponential economic growthIntroductionVocabularyTranscriptSummary Why AI will spark exponential economic growth Link: https://www.ted.com/talks/cathie_wood_why_ai_will_spark_exponential_economic_growth? …