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

news/2024/7/10 20:29:34 标签: 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_*方法,可以限定计算后的结果不超过目标类型的最大值或不低于最小值。

例如:

rust">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提供了更高的精度。

rust">let variable_float = 2.0;
let variable_f32: f32 = 3.0;

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

rust">let variable_f64: f64 = 4.0;

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

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

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

来看个例子

rust">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:

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

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

rust">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关键字来实现这一转换:

rust">let num_i32: i32 = 42;  
let num_f64: f64 = num_i32 as f64;

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

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

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

rust">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.niftyadmin.cn/n/5449176.html

相关文章

johnson最短路模板(未完成,自用)

johnson最短路 https://www.starrycoding.com/problem/100 关键就在于,解决dijkstra不能处理负权值的问题,先用spfa或者bellman-ford得到所有点到虚点的最短距离,可以称之为势能。然后通过势能对所有边进行处理,处理过后保证了所…

Springboot实现合并单元格的excel文件导入到数据库(多模块)

最近做项目的时候一直在遇到excel导入导出的问题,本篇博文也是为了记录我这几天的血泪史,并做以记录,希望各位看完之后能有所收获。 以下是我excel文档里面的具体内容: excel文件中的编码信息属于另外一张表,所以以下…

vue基础——java程序员版(总集)

前言: ​ 这是一个java程序员的vue学习记录。 ​ vue是前端的主流框架,按照如今的就业形式作为后端开发的java程序员也是要有所了解的,下面是本人的vue学习记录,包括vue2的基本使用以及引入element-ui,使用的开发工具…

es同义词配置规则

同义词配置有两种: 1,a>b: 通俗的来讲,就是尽管用户输入的是a,但是es在查询的是会转成b去搜索,">"左边的词全部会被右边的词替换。 2,a,b:通俗的来讲,就是不管用户输入的是a还是b,es在查询的是用a,或者b搜索.比如 保温杯,杯子,用户输入的是"保温杯"…

Chinese-LLaMA-Alpaca-2模型量化部署测试

简介 Chinese-LLaMA-Alpaca-2基于Meta发布的可商用大模型Llama-2开发, 是中文LLaMA&Alpaca大模型的第二期项目. 量化 模型的下载还是应用脚本 bash hfd.sh hfl/chinese-alpaca-2-13b --tool aria2c -x 8应用llama.cpp进行量化, 主要参考该教程. 其中比较折腾的是与BLAS…

rust - 将bitmap位图文件另存为png格式

本文提供了一种将bitmap位图文件另存为png格式文件的方法。 添加依赖 cargo add image转换函数 use image::{codecs::png::PngEncoder, GenericImageView, ImageEncoder, ImageFormat,ImageResult, }; use std::{fs,io::{BufReader, BufWriter},path::Path, };/// 将bitmap位…

Java后端需要掌握的前端知识

第一章. HTML 与 CSS HTML 是什么&#xff1a;即 HyperText Markup language 超文本标记语言&#xff0c;咱们熟知的网页就是用它编写的&#xff0c;HTML 的作用是定义网页的内容和结构。 HyperText 是指用超链接的方式组织网页&#xff0c;把网页联系起来Markup 是指用 <…

二叉树的遍历及线索二叉树试题解析

一、单项选择题 01.在下列关于二叉树遍历的说法中&#xff0c;正确的是( C ). A.若有一个结点是二叉树中某个子树的中序遍历结果序列的最后一个结点&#xff0c;则它一定是该子树的前序遍历结果序列的最后一个结点 B.若有一个结点是二叉树中某个子树的前序遍历结果序列的最后一…