基本数据类型

整型

整型溢出

debug 模式会检查整型溢出,而 release 模式则不会。

显示处理溢出可以使用标准库对原始数字类型提供的方法:

  • wrapping_*:包装溢出,按照补码进行循环。
  • checked_*:检查溢出,返回 None 值。
  • overflowing_*:返回补码循环的值和一个指示是否溢出的布尔值。
  • saturating_*:饱和溢出,限定越界结果为最大值、最小值。
    其中 * 表示具体的方法,包括 addsubmuldiv 等。

浮点类型

Rust 中的浮点类型有两种:f32f64,但是现在CPU中他俩的速度几乎相同,所以默认使用 f64

浮点数陷阱

因为计算机中的小数用二进制存储,有些在十进制中可以精确表示的数,在计算机中无法精确表示。例如,

1
2
3
4
fn main() {
// 断言0.1 + 0.2与0.3相等
assert!(0.1 + 0.2 == 0.3);
}

此断言会失败。如果一定要比较,可以使用 (0.1_f64 + 0.2 - 0.3).abs() < 0.00001 来判断。

NaN (Not a Number)

  • 数学上未定义的结果会返回 NaN,例如:-42_f64.sqrt() (注:sqrtf64 的方法)。
  • NaN 不能用于比较,任何数与它比较时,除了!=,其它诸如 ==<><=>= 等,都会返回 false
  • 可以使用 is_nan() 方法来检查一个数是否为 NaN,例如:(-42_f64).sqrt().is_nan()(注:- 运算符优先级低于 .,不加括号会导致错误结果)。

数字运算和位运算

  • 数字运算包括加法(+)、减法(-)、乘法(*)、除法(/)和取模运算(%)。
  • 位运算包括按位与(&)、按位或(|)、按位异或(^)、按位取反(!)、左移(<<)和右移(>>)。

其中,移位不应超过该整型的位数,否则会报错。因为超过超过位数的移位结果要么全0要么全1,不如直接写0或-1。

序列

  • 使用 1..10 可以生成一个从 1 到 9 的序列(不包含 10),或者使用 1..=10 生成一个从 1 到 10 的序列(包含 10)。
  • 序列只允许数字或者字符类型。

使用 As 进行类型转换

最常用于将一个基本类型转换为另一个,例如,

1
2
3
let x: i8 = 10;
let y: i32 = x as i32;
println!("{}", y);

大到小可能会丢失数据。

也可完成地址和指针之间的转换(暂略)。

有理数和复数

以下数值并未包含在标准库内,但是可以使用 num 库来实现。

  • 有理数和复数
  • 任意大小的整数和任意精度的浮点数
  • 固定精度的十进制小数,常用于货币相关的场景

一个复数的例子:

1
2
3
4
5
6
7
8
9
use num::complex::Complex;

fn main() {
let a = Complex { re: 2.1, im: -1.2 };
let b = Complex::new(11.1, 22.2);
let result = a + b;

println!("{} + {}i", result.re, result.im)
}

字符类型(char)

  • Rust 的字符只能用 ‘’ 来表示, “” 是留给字符串的。
  • Rust 的字符是 UTF-32 编码,每个字符占用 4 个字节(注:不同于字符串,字符串是 UTF-8 编码,每个字符占用 1~4 个字节)。

布尔类型(bool)

  • Rust 的布尔类型只有 truefalse 两个值。
  • 每个布尔值占用 1 个字节。

单元类型(Unit)

  • Rust 的单元类型只有一个值 (),也被称为空元组(empty tuple)。
  • 任何没有显式声明返回值类型的函数,默认返回 ()
  • 每个 () 值占用 0 个字节。
  • 可以用作 map 的值,表示不关心具体值,只关心 key

语句与表达式

  • 语句(statement):不返回值。
  • 表达式(expression):返回值,不包含分号。

函数

  • 函数名和变量名使用蛇形命名法(snake case),例如 fn add_two() {}
  • 函数的位置可以随便放, Rust 不关心我们在哪里定义了函数,只要有定义即可
  • 每个函数参数都需要标注类型,例如 fn add_two(a: i32, b: i32) -> i32 {}

例:

1
2
3
fn add(i: i32, j: i32) -> i32 {
i + j
}

返回值

返回值要与类型匹配,可以在函数结尾使用表达式返回,也可以使用 return 语句提前返回。

永不返回的发散函数 !

当用 ! 作函数返回类型的时候,表示该函数永不返回,也就是发散函数(diverging functions),用作特殊情况。