02.数据类型
数据类型概述
- 在 rust 中,数据类型主要有标量和复合类型
- rust 是静态的编译型语言,在编译时需要知道所有的变量的类型,因此:
- 一般情况下, rust 编译器可以推断出绝大多数的变量类型
- 在同一个变量可能具有的变量类型种类比较多时,必须要为变量指定类型标注,否则会导致编译错误
指定类型标注
在这个示例中,需要为变量 x 指定一个整数类型,这里指定了 u32 ,因为整数类型很多,如 u32 , i32 等, rust 不知道该整数具体的类型:
fn main() {
let x: u32 = "12".parse().expect("这不是数字");
println!("x = {}", x)
}如果不指定类型,将会报错:
...
2 | let x = "12".parse().expect("这不是数字");
| ^ ----- type must be known at this point
...标量类型
整数类型
整数类型分为有符号和无符号类型,分别用 i 和 u 表示,如 u32 是无符号类型,占据 32 bit 的空间。
rust 的整数类型的长度分别有 8、16、32、64 和 128 bit 。
除了 i32 等,还有 isize 和 usize 类型,分别表示当前计算机的位数的长度,如果计算机是 64 位的,则长度为 64 bit 。
字面值
| 数字形式 | 示例 |
|---|---|
| 十进制 | 98_222 |
| 十六进制 | 0xff |
| 八进制 | 0o77 |
| 二进制 | 0b1111_0000 |
字节( Byte ,仅限于 u8 类型) | b‘A’ |
NOTE
除了字节类型外,所有整数数字形式都允许以类型作为后缀,如 57u8 。
整数的默认类型是 i32 。
整数溢出
如果整数溢出,则:
在调试模式下编译:程序 panic
在发布模式下编译:执行“环绕”操作,如将 256 变为 0,将 257 变为 1 等,程序不会 panic
浮点类型
浮点类型分为单精度 f32 和双精度 f64 类型,其中 f64 为默认类型。
布尔类型
分为 true 和 false 类型,占用大小为 1 字节,符号为 bool 。
字符类型
使用 char 声明一个字符,使用单引号,占用 4 个字节。
其中, rust 中的字符类型为 unicode 标量值,可以表示比 ascii 更多的内容。
复合类型
复合类型是可以将多个类型的值放到一个类型里,如 Python 中的列表或元组等。Rust 提供 2 种基础的复合类型:元组和数组
元组
元组在小括号中声明,元组的长度不可变。
声明一个元组的示例如下,其中,访问元组内部元素使用点标记法访问,使用点 + 元素的索引:
let tup: (i32, f64, u8) = (500, 6.4, 1);
println!("tup = {}, {}, {}", tup.0, tup.1, tup.2);元组解构
使用模式匹配解构一个元组的值,接上例:
let (x, y, z) = tup;
println!("x = {}, y = {}, z = {}", x, y, z)数组
数组在中括号中声明。
TIP
如果想要数据存放在**栈(stack)而不是堆(heap)**上,或者想要保证固定数量的元素,使用数组更好。
声明一个数组的例子:
let month = [
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
];数组的类型表示
格式如下:
[类型; 长度]
如:
let a: [i32; 5] = [1, 2, 3, 4, 5];数组的特殊声明
就像数组的类型表示那样,第一个元素不再是类型,而是数组元素的初始值,如 [3; 5] ,则表示该数组有 5 个元素,每个元素的值为 3 :
let b = [3; 5];
println!("b = {:?}", b)输出:b = [3, 3, 3, 3, 3]
数组元素访问
和 Python 一样,使用索引访问数组中的元素。
如果访问的元素下标超出了数组长度,在编译时不会报错(非绝对,在某些简单的情况下会报错),但在运行时会报错。
rust 不允许访问越界的内存。