Rust笔记(二)
基本数据类型
整型
整型溢出
debug 模式会检查整型溢出,而 release 模式则不会。
显示处理溢出可以使用标准库对原始数字类型提供的方法:
wrapping_*:包装溢出,按照补码进行循环。checked_*:检查溢出,返回None值。overflowing_*:返回补码循环的值和一个指示是否溢出的布尔值。saturating_*:饱和溢出,限定越界结果为最大值、最小值。
其中*表示具体的方法,包括add,sub,mul,div等。
浮点类型
Rust 中的浮点类型有两种:f32 和 f64,但是现在CPU中他俩的速度几乎相同,所以默认使用 f64。
浮点数陷阱
因为计算机中的小数用二进制存储,有些在十进制中可以精确表示的数,在计算机中无法精确表示。例如,
1 | fn main() { |
此断言会失败。如果一定要比较,可以使用 (0.1_f64 + 0.2 - 0.3).abs() < 0.00001 来判断。
NaN (Not a Number)
- 数学上未定义的结果会返回
NaN,例如:-42_f64.sqrt()(注:sqrt是f64的方法)。 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 | let x: i8 = 10; |
大到小可能会丢失数据。
也可完成地址和指针之间的转换(暂略)。
有理数和复数
以下数值并未包含在标准库内,但是可以使用 num 库来实现。
- 有理数和复数
- 任意大小的整数和任意精度的浮点数
- 固定精度的十进制小数,常用于货币相关的场景
一个复数的例子:
1 | use num::complex::Complex; |
字符类型(char)
- Rust 的字符只能用 ‘’ 来表示, “” 是留给字符串的。
- Rust 的字符是 UTF-32 编码,每个字符占用 4 个字节(注:不同于字符串,字符串是 UTF-8 编码,每个字符占用 1~4 个字节)。
布尔类型(bool)
- Rust 的布尔类型只有
true和false两个值。 - 每个布尔值占用 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 | fn add(i: i32, j: i32) -> i32 { |
返回值
返回值要与类型匹配,可以在函数结尾使用表达式返回,也可以使用 return 语句提前返回。
永不返回的发散函数 !
当用 ! 作函数返回类型的时候,表示该函数永不返回,也就是发散函数(diverging functions),用作特殊情况。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Zone of Lix!
评论




