Rust教程:How to Rust-基本类型

专栏简介

本专栏是优质Rust技术专栏,推荐精通一门技术栈的蟹友,不建议完全无计算机基础的同学

感谢Rust圣经开源社区的同学,为后来者提供了非常优秀的Rust学习资源

本文使用:

  • 操作系统macOS Sonoma 14 / Apple M1
  • 编译器:Rustc & Cargo

感谢一路相伴的朋友们,感谢你们的支持 ^ _ ^

Rust教程:How to Rust-基本类型


目录

专栏简介

更新记录

前言

整型

整型溢出

浮点型

NaN

 使用As进行类型转换

结语

本文参考文献


更新记录

2024.3.24 发布文章


前言

Rust中的整型怎么写?整型溢出会怎么样?浮点型呢?NaN是什么?如何进行类型转换?


整型

Rust的类型系统与其他编程语言有许多相似之处,但Rust对类型的处理有其独特之处。在Rust中,整数类型的符号大小直接体现在类型名称中,这有助于清晰地表达每个类型的取值范围。

Rust的整数类型如下:

Rust整数类型
长度有符号类型无符号类型
8位i8u8
16位i16

u16

32位i32u32
64位i64

u64

128位i128u128
视架构isizeusize

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

在Rust编程语言中,isizeusize是两个与平台相关的整数类型。它们的大小取决于目标机器的指针大小。isize是一个有符号整数类型,其大小与机器的字大小相同。在32位系统上,isize通常是32位;在64位系统上,isize通常是64位。usize则是相应的无符号版本。

整型溢出

关于整型溢出,Rust有一些特别的规则。当在debug模式编译时,Rust会检查整型溢出,并在发现溢出时使程序panic(即崩溃)。然而,在release模式下编译时,Rust不检测溢出,而是按照补码循环溢出的规则处理。这意味着大于该类型最大值的数值会被转换成该类型能够支持的对应的最小值。例如,在u8类型中,256会变成0,257会变成1,以此类推。

为了显式处理可能的溢出,Rust标准库为原始数字类型提供了一系列方法:

  • 使用wrapping_*方法在所有模式下都按照补码循环溢出规则处理,例如wrapping_add
  • 如果使用checked_*方法时发生溢出,则返回None值。
  • 使用overflowing_*方法返回该值和一个指示是否存在溢出的布尔值。
  • 使用saturating_*方法,可以限定计算后的结果不超过目标类型的最大值或不低于最小值。

例如:

let result1 = (250_u8).wrapping_add(10); // 结果是 4
let result2 = (120_i8).wrapping_add(10); // 结果是 -126
let result3 = (300_u16).wrapping_mul(800); // 结果是 43392
let result4 = (-100_i8).wrapping_sub(100); // 结果是 56

在这些例子中,wrapping_*方法用于在溢出时按照补码循环溢出的规则进行处理,而不是使程序崩溃。然而,需要注意的是,依赖这种默认行为的代码通常被认为是错误的,因为它可能导致程序中的逻辑错误或数据损坏。在编写涉及整数运算的代码时,应该仔细考虑如何处理可能的溢出情况,并使用适当的方法来检查或处理它们


浮点型

浮点类型数字是带有小数点的数值,在Rust中,主要有两种浮点类型:f32f64,分别对应32位和64位大小的浮点数。默认情况下,Rust使用f64作为浮点类型,因为在现代CPU上,尽管f32f64的速度相差无几,但f64提供了更高的精度。

let variable_float = 2.0;
let variable_f32: f32 = 3.0;

变量variable_float的类型是默认的f64,而变量variable_f32的类型则是显式声明的f32。当然,你也可以显式声明f64类型的变量,例如:

let variable_f64: f64 = 4.0;

使用浮点数时,如果不谨慎,可能会带来一些潜在的危险。这主要有两个原因:

首先,浮点数通常是用来近似表达你想要的数值。请注意,这里的“近似表达”是因为浮点数类型是基于二进制实现的,而我们通常使用的数字则是基于十进制的。例如,数值0.1在二进制中无法精确表示,这导致了一定的歧义。尽管浮点数能够代表真实的数值,但由于其底层格式的限制,它通常受限于定长的浮点数精度。如果你需要表达完全精确的真实数字,则需要使用具有无限精度的数学库。

其次,浮点数在某些特性上是反直觉的。虽然可以使用>>=等运算符对浮点数进行比较,但在某些场景下,这种直觉上的比较特性可能会导致错误。f32f64上的比较运算实现了std::cmp::PartialEq特性,但并没有实现std::cmp::Eq特性,而后者在其他数值类型上都有定义。

来看个例子

fn main()
{assert_eq!(0.1 + 0.2, 0.3); // 这行代码会触发 panic,因为二进制精度问题导致 0.1 + 0.2 不严格等于 0.3
}

上述代码中,第三行是一个断言,断言0.1 + 0.2的结果就是0.3。然而,由于二进制精度的问题,0.1 + 0.2并不严格等于0.3,它们之间可能存在小数点后某位的误差,这与大多数编程语言中的浮点数行为是一致的。

NaN

对于数学上未定义的结果,如负数开平方根,Rust的浮点数类型会使用NaN(Not a Number)来处理这些情况。任何与NaN进行交互的操作都会返回NaN,并且NaN不能用于比较(如断言),这会导致程序崩溃。

例如,以下代码会产生NaN:

fn main()
{let variable = (-1.1_f64).sqrt();
}

为了避免程序因NaN而崩溃,我们可以使用一些方法来检查数值是否为NaN,例如使用.is_nan()方法:

fn main()
{let variable = (-1.1_f64).sqrt();if variable.is_nan(){println!("NaN")}
}

使用.is_nan()可以帮助我们安全地处理可能产生NaN的浮点数运算。 

 使用As进行类型转换

在Rust中,as关键字用于在原始类型(如i64f64u64char等)之间进行类型转换。然而,需要注意的是,as关键字并不适用于复合类型,比如String或其他用户定义的类型。对于复合类型的转换,通常需要使用其他方法或函数。

例如,如果你有一个i32类型的变量,并希望将其转换为f64类型的浮点数,你可以使用as关键字来实现这一转换:

let num_i32: i32 = 42;  
let num_f64: f64 = num_i32 as f64;

但是,as关键字的使用是有限制的,它只能在那些具有明确定义转换规则的类型之间起作用。如果尝试在不兼容的类型之间进行转换,Rust编译器会报错。例如,下面的代码尝试将一个String转换为i32,这是不允许的,因为Stringi32之间没有直接的转换关系:

let str_num = "123".to_string();  
let num_i32: i32 = str_num as i32; // 这行会报错,因为 String 不能直接转换为 i32

在上面的代码中,尝试使用as来转换str_num变量会导致编译错误,因为String类型不能直接用as关键字转换为i32类型。如果需要将字符串转换为整数,你需要使用其他方法,比如parse方法:

let str_num = "123";  
let num_i32: i32 = str_num.parse().unwrap(); // 使用 parse 方法来将字符串转换为整数

在上面的代码中,我们使用了parse()方法,该方法尝试将字符串解析为相应的数值类型,并返回一个Result枚举,表示解析操作是否成功。使用unwrap()方法可以获取解析结果,但如果解析失败(比如字符串不是有效的数字表示),则会触发panic。在实际应用中,通常需要对parse()的返回值进行更健壮的错误处理。

因此,在使用as进行类型转换时,需要确保转换的类型之间具有明确定义的转换关系,并且不适用于复合类型或没有直接转换关系的类型。对于更复杂的类型转换需求,需要利用Rust提供的相应函数或方法。


结语

如果本文有任何问题欢迎在评论去指出,如果喜欢这篇文章,希望能点赞评论关注

如果你们身边有像你提起过这个领域的,或者希望可以和ta一起进步的,把这篇文章分享给ta吧

本文共3646字


本文参考文献

Rust圣经

文心一言 

菜鸟求助,使用 isize 或 usize 作为索引类型更加灵活 - Rust语言中文社区

在 Rust 中处理整数溢出

https://www.cnblogs.com/ywxt/p/11801778.html

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

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

相关文章

ubuntu编译OpenCV and seetaFace2

opencv opencv-4.5.2 opencv_contrib-4.5.2 SeetaFace2 SeetaFace2-master https://github.com/seetafaceengine 指定安装目录,和OpenCV放一个目录下了 安装前 安装 安装后 Qt安装 Windows下 Linux下 报错1 原因: 报错…

Opencv 读取灰度图像会识别为3通道问题

场景: 我们都知道灰度图或者红外图都是单通道图片,而彩色图片是三通道图片。但是当我们用img.shape读取灰度图/红外图片的时候返回的却是三通道结果。 import cv2img_path r灰度图 img cv2.imread(img_path) print(img.shape) # 如果我将图片灰度处理…

HTTP状态 405 - 方法不允许

方法有问题。 用Post发的请求&#xff0c;然后用Put接收的。 大家也可以看看是不是有这种问题 <body><h1>HTTP状态 405 - 方法不允许</h1><hr class"line" /><p><b>类型</b> 状态报告</p><p><b>消息…

Rust控制台输出跑马灯效果,实现刷新不换行,实现loading效果

要在 Rust 中实现控制台刷新而不换行&#xff0c;以实现类似 "loading" 状态的效果&#xff0c;你可以使用 \r&#xff08;回车符&#xff09;来覆盖上一行的内容。 use std::io::{self, Write}; use std::thread; use std::time::Duration;fn main() {let loading_…

没学数模电可以玩单片机吗?

我们首先来看一下数电模电在单片机中的应用。数电知识在单片机中主要解决各种数字信号的处理、运算&#xff0c;如数制转换、数据运算等。模电知识在单片机中主要解决各种模拟信号的处理问题&#xff0c;如采集光照强度、声音的分贝、温度等模拟信号。而数电、模电的相互转换就…

MongoDB 7.x 绑定多个IP(bindIp)和IP范围段(IP/24)

早上安装了最新版的MOngoDB7.0&#xff0c;仅仅是想测试一些功能&#xff0c;暂无复杂操作的想法。 于是在远程的机器上&#xff0c;安装启动&#xff0c;一切正常。 网上找了教程&#xff0c;绑定IP的做法基本是修改mongod.cfg文件中的bindIp属性&#xff1a; Windows系统的…

蓝桥杯_day6

文章目录 不同路径不同路径II拿金币珠宝的最高价值 不同路径 【题目描述】 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为…

十一、Spring源码学习之registerListeners方法

registerListeners()方法 protected void registerListeners() {// Register statically specified listeners first.//获取容器中事件监听并存放到多播器中 applicationListenersfor (ApplicationListener<?> listener : getApplicationListeners()) {getApplicationE…

Flutter——用户关闭键盘后强制拉起键盘

Bug背景 今天在弄输入框的时候&#xff0c;发现用户手动关闭键盘后&#xff0c;因为自定义组件的特殊性&#xff0c;我在点击输入框后并没有唤起键盘。 一般点击输入框或者某个组件&#xff1a; GestureDetector(onTap: () {FocusScope.of(context).requestFocus(_focusNode…

解决element ui中的el-tree组件default-checked-keys默认勾选节点问题

解决element ui中的el-tree组件default-checked-keys默认勾选节点问题 需求解决方法方法1方法2 需求 选中子节点的时候&#xff0c;父节点必须被选中&#xff0c;但是仅展示被选中父节点和子节点 解决方法 方法1 html部分代码&#xff1a; <el-treeclass"filter-tr…

【I.MX6ULL移植】Ubuntu-base根文件系统移植

1.下载Ubuntu16.04根文件系统 http://cdimage.ubuntu.com/ 1 2 3 4 5 2.解压ubuntu base 根文件系统 为了存放 ubuntu base 根文件系统&#xff0c;先在 PC 的 Ubuntu 系统中的 nfs 目录下创建一个名为 ubuntu_rootfs 的目录&#xff0c;命令如下&#xff1a; 【注意&…

基于单片机病房呼叫系统数码管显示房号设计

**单片机设计介绍&#xff0c;基于单片机病房呼叫系统数码管显示房号设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机病房呼叫系统数码管显示房号设计概要主要涵盖了利用单片机技术实现病房呼叫系统&#xff0c;并…

mac上查看以及修改DNS配置

前言 特殊场景下&#xff0c;我们可能需要本机上的DNS配置 操作步骤 查看 mac上的 已有的dns配置# 如果你使用的是以太网连接&#xff0c;将命令中的 "Wi-Fi" 替换为 "Ethernet"。 networksetup -getdnsservers Wi-Fi修改DNS配置# DNS_SERVER_IP_ADDRES…

WPF 多路绑定、值转换器ValueConvert、数据校验

值转换器 valueconvert 使用ValueConverter需要实现IValueConverter接口&#xff0c;其内部有两个方法&#xff0c;Convert和ConvertBack。我们在使用Binding绑定数据的时候&#xff0c;当遇到源属性和目标控件需要的类型不一致的&#xff0c;就可以使用ValueConverter&#xf…

GT收发器第一篇_总体结构介绍

文章目录 前言GT收发器介绍 前言 之前写过一篇简单介绍GT的文章https://blog.csdn.net/m0_56222647/article/details/136730026&#xff0c;可以先通过这篇文章对整体进行简单了解一下。 GT收发器介绍 参考xilinx手册ug476 对于7系列的FPGA&#xff0c;共有3个系列&#xf…

【MATLAB源码-第19期】matlab基于导频的OFDM系统瑞利信道rayleigh的信道估计仿真,输出估计与未估计误码率对比图。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 正交频分复用&#xff08;英语&#xff1a;Orthogonal frequency-division multiplexing, OFDM&#xff09;有时又称为分离复频调制技术&#xff08;英语&#xff1a;discrete multitone modulation, DMT&#xff09;&#x…

数据仓库——事务、快照和累积快照事实表

事务、快照和累积快照 事务事实表跟踪定义业务过程的个体行为&#xff0c;并且支持几种描述这种行为事实。可以提供丰富的分析型能力&#xff0c;时常充当原子数据的粒度化仓库快照事实表周期性地采样状态度量&#xff0c;这些度量与一系列事务的累积效果相当&#xff0c;但是…

Android和IOS应用开发-Flutter应用让屏幕在 app 运行期间保持常亮的方法

文章目录 Flutter应用让屏幕在 app 运行期间保持常亮的方法方法一&#xff1a;使用系统插件方法二&#xff1a;使用 Widgets注意事项 Flutter应用让屏幕在 app 运行期间保持常亮的方法 在 Flutter 开发中&#xff0c;可以使用以下两种方法让屏幕在 app 运行期间保持常亮&#…

【数据库监控系列】Prometheus+Alertmanager+Grafana容器化部署

【数据库监控系列】PrometheusAlertmanagerGrafana容器化部署 快速安装docker环境被监控端部署exporter配置Redis exporter配置MySQL exporter 部署Prometheus和GrafanaPrometheus配置文件Alertmanager配置文件rule_files告警规则文件docker-compose部署文件常见报错信息 配置G…

【MySQL】6.MySQL主从复制和读写分离

主从复制 主从复制与读写分离 通常数据库的读/写都在同一个数据库服务器中进行&#xff1b; 但这样在安全性、高可用性和高并发等各个方面无法满足生产环境的实际需求&#xff1b; 因此&#xff0c;通过主从复制的方式同步数据&#xff0c;再通过读写分离提升数据库的并发负载…