类型,第1部分
在"语法"部分中,compute
的输入参数类型为 u32
。让我们来解开这个是什么意思。
基本类型
u32
是Rust的基本类型之一。基本类型是语言最基本的构建模块。它们内置于语言本身中——也就是说,它们不是由其他类型定义的。
你可以组合这些基本类型来创建更复杂的类型。我们很快就会看到怎么做。
整数
具体来说,u32
是一个无符号32位整数。
整数是一个不包含小数部分的数字。例如,1
是一个整数,而1.2
不是。
有符号与无符号
整数可以是有符号或无符号的。无符号整数只能表示非负数(即0
或更大)。有符号整数可以表示正数和负数(例如-1
、12
等)。
u32
中的u
代表无符号。等效的有符号整数类型是i32
,其中i
代表整数(即任何整数,正数或负数)。
位宽
u32
中的32
是指用于在内存中表示该数字的位数1。位数越多,可以表示的数字范围就越大。
Rust支持多个位宽的整数:8
、16
、32
、64
、128
。
用32位,u32
可以表示从0
到2^32 - 1
(又称u32::MAX
)的数字。
用相同的位数,有符号整数(i32
)可以表示从-2^31
到2^31 - 1
的数字(即从i32::MIN
到i32::MAX
)。
i32
的最大值小于u32
的最大值,因为一个位用于表示数字的符号。
更多关于有符号整数在内存中是如何表示的详细信息,请查看二补码表示。
总结
将有符号/无符号和位宽两个变量结合,我们得到以下整数类型:
位宽 | 有符号 | 无符号 |
---|---|---|
8位 | i8 | u8 |
16位 | i16 | u16 |
32位 | i32 | u32 |
64位 | i64 | u64 |
128位 | i128 | u128 |
字面值
字面值是在源代码中表示固定值的符号。例如,42
是Rust中表示四十二这个数字的字面值。
字面值的类型注解
但是Rust中所有值都有类型,所以...42
是什么类型呢?
Rust编译器会尝试根据使用环境来推断字面值的类型。如果你不提供任何上下文信息,编译器将默认为i32
整数字面值。如果你想使用其他类型,你可以在字面值后面添加所需的整数类型作为后缀——例如2u64
表示一个显式声明为u64
类型的2。
字面值中的下划线
你可以使用下划线_
来提高大数字的可读性。例如,1_000_000
和1000000
是相同的。
算术运算符
Rust支持以下用于整数的算术运算符2:
+
用于加法-
用于减法*
用于乘法/
用于除法%
用于取余
这些运算符的优先级和结合性规则与数学中的相同。你可以使用括号来覆盖默认的优先级,例如2 * (3 + 4)
。
⚠️ 警告
当用于整数类型时,除法运算符
/
执行整数除法。 换句话说,结果会被截断为0。例如,5 / 2
的结果是2
,而不是2.5
。
没有自动类型强制转换
正如我们在上一个练习中讨论的,Rust是一种静态类型语言。具体来说,Rust对类型强制转换非常严格。即使转换是无损的,它也不会自动将一个值从一种类型转换为另一种类型3,你必须显式地进行转换。
例如,你不能将一个u8
值赋给类型为u32
的变量,即使所有的u8
值都是有效的u32
值:
#![allow(unused)] fn main() { let b: u8 = 100; let a: u32 = b; }
它会抛出编译错误:
error[E0308]: mismatched types
|
3 | let a: u32 = b;
| --- ^ expected `u32`, found `u8`
| |
| expected due to this
|
我们将在本课程的后面看到如何在不同类型之间进行转换。
参考资料
本节的练习位于 exercises/02_basic_calculator/01_integers
进一步阅读
好的,以下是这些内容的翻译:
位是计算机中最小的数据单位。它只能有两个值:0或1。
Rust不允许你定义自定义运算符,但它让你可以控制内置运算符的行为。在我们讨论了特征之后,将会在本课程的后面讨论运算符重载。
对于这个规则也有一些例外,主要与引用、智能指针和人体工程学有关。我们将稍后介绍这些内容。目前,"所有转换都是显式的"这个心智模型将为你提供很好的服务。