02-Rust基本类型之数值类型

14 阅读6分钟

02-Rust基本类型之数值类型

Rust基本类型

Rust 每个值都有确切的数据类型,大致可以分为两类(基本类型和复合类型)

🍎基本类型
数值类型:
  有符号整数 (i8, i16, i32, i64, isize)
  无符号整数 (u8, u16, u32, u64, usize) 
  浮点数 (f32, f64)、以及有理数、复数
字符串:字符串字面量和字符串切片 &str
布尔类型:truefalse
字符类型:表示单个 Unicode 字符,存储为 4 个字节
单元类型:即 () ,其唯一的值也是 ()
🍎类型推导与标注

Rust也包含有类型推导,跟其他语言差不多。就是推导数据类型。

数值类型

👉认识无符号数和有符号数

无符号数和有符号数是计算机中表示整数的两种方式,主要区别在于是否允许表示负数

🍎 有符号数(Signed Integer)

有符号数(正数、零和负数的整数)。计算机使用一个额外的位(通常是最高位)来表示符号。常见的表示方式有补码表示法。

  • 补码表示法:最高位(最左边的一位)用来表示符号。0表示正数,1表示负数。
    • 例如,8位有符号数:11111111 表示 -1,00000001 表示 +1。
    • 通过补码方式,可以轻松进行加减运算。
🍎无符号数(Unsigned Integer)

无符号数(正数和零),没有符号位,因此所有位都用来表示数值大小。因为没有符号位,所以它的值域比有符号数多一倍。

  • 例如,8位无符号数的范围是从 0 到 255(即 0 到 28−1)
  • 无符号数的表示只能是正整数和零,无法表示负数
🍎举例说明:
  • 8位有符号数:表示的范围是 -128 到 +127。
  • 8位无符号数:表示的范围是 0 到 255。

👉整数类型

rust之中的整数可以概括为(有无符号 + 类型大小(位数))

Rust 整型默认使用 let i = 1,那 i 就是 i32 类型,该类型也往往是性能最好的。

表示方法:没有小数部分的数字 i32 类型表示有符号的 32 位整数

i代表有符号(英文单词 _integer_ 缩写)

u代表无符号 (英文单词 unsigned 缩写)

🍎内置的整数类型
长度有符号类型无符号类型
8 位i8u8
16 位i16u16
32 位i32u32
64 位i64u64
128 位i128u128
视架构而定isizeusize
🍎整型溢出

假设有一个 u8 ,它可以存放从 0 到 255 的值。那么当你将其修改为范围之外的值,比如 256,则会发生整型溢出(也就是当一个值超出它的整数类型的最大范围时会发生)

  • 判定规则

当在 debug 模式编译时,Rust 会检查整型溢出,存在问题则使程序在编译时 panic(崩溃,Rust 使用这个术语来表明程序因错误而退出)

发生溢出以后,值会变成这个整型的最小值,遵循的是补码循环溢出(two’s complement wrapping)的规则

我们可以写一段代码进行检验

fn main() {
    // 定义一个 u8 类型的变量,并赋予其最大值 255
    let max_u8: u8 = 255;
    println!("最大无符号 8 位整数值: {}", max_u8);

    // 将变量加 1,导致溢出
    let overflow_u8 = max_u8.wrapping_add(1);
    println!("溢出后的值: {}", overflow_u8);
}

// 输出
最大无符号 8 位整数值: 255
溢出后的值: 0
  • 如何跳过校验呢

使用 --release 参数进行 release 模式构建时,Rust 检测溢出。

👉浮点类型

Rust 中浮点类型 分为f32f64两种,默认为f64,根据 IEEE-754 标准实现

特性f32f64(默认为这个)
大小32 位64 位
精度单精度浮点数,精度约为 7 位有效数字双精度浮点数,精度约为 15 位有效数字
默认类型
范围大约 ±1.5 × 10^−45 到 ±3.4 × 10^38大约 ±5.0 × 10^−324 到 ±1.8 × 10^308
使用场景当对内存占用要求较高时(例如嵌入式系统)当需要更高精度时,例如科学计算
性能在某些 CPU 上速度较快,但精度较低在现代 CPU 上与 f32
性能相似,但提供更高精度
表示方式采用 IEEE 754 单精度浮点数标准采用 IEEE 754 双精度浮点数标准
🍎浮点类型数字

两种基本类型: f32f64

默认浮点类型是 f64

fn main() {
    let x = 2.0; // f64
    let y: f32 = 3.0; // f32
}
🍎浮点数陷阱
🍎NaN

Rust 的浮点数类型使用 NaN (not a number) 来处理数学上未定义的结果

👉数字运算

Rust 支持所有数字类型的基本数学运算,加减乘除如下

fn main() {
    // 加法
    let sum = 5 + 10;

    // 减法
    let difference = 95.5 - 4.3;

    // 乘法
    let product = 4 * 30;

    // 除法
    let quotient = 56.7 / 32.2;

    // 求余
    let remainder = 43 % 5;
}

👉位运算

Rust 的位运算如下:

运算符说明
& 位与相同位置均为1时则为1,否则为0
位或相同位置只要有1时则为1,否则为0
^ 异或相同位置不相同则为1,相同则为0
! 位非把位中的0和1相互取反,即0置为1,1置为0
<< 左移所有位向左移动指定位数,右位补0
>> 右移所有位向右移动指定位数,带符号移动(正数补0,负数补1)

👉序列(Range)

Rust 提供了序列(Range)方式用来生成连续的数值

1..5,生成从 14 的连续数字,不包含 5 

1..=5,生成从 15 的连续数字,包含 5

常用于循环中:

//数字
for i in 1..=5 {
    println!("{}",i);
}

// 最终程序输出
1
2
3
4
5

//字符 
for i in 'a'..='z' {
    println!("{}",i);
}

需要注意的是:序列只允许用于数字或字符类型因为它们可以连续起来。其实思考一下,弄个汉字,完全不知道一个汉字背后应该放个啥。

编译器在编译期同时检查该序列是否为空

👉As类型转换

As 来完成一个类型到另一个类型的转换,这里有点类似TS

fn main() {
    let i_terger:i32 = 10;
    let f_terger:f64=i_terger as f64;
    println!("i_terger is: {}", i_terger);
    println!("f_terger is: {}", f_terger);
}

// 输出
i_terger is: 10
f_terger is: 10

👉有理数和复数

Rust 中处理有理数(Rational Numbers)和复数(Complex Numbers)并没有内建的类型

我们可以使用 num 外部库来处理有理数和复数,它提供了 RationalComplex 类型

这里后续进行补充完善