目录
思维导图
1. 数据类型概述
Rust是一种静态类型语言,所有变量的类型在编译时必须明确。Rust支持两种主要的数据类型:标量类型和复合类型。
1.1 标量类型
标量类型表示单一值,Rust的四种主要标量类型包括:
- 整数(Integer)
- 浮点数(Floating-point)
- 布尔值(Boolean)
- 字符(Character)
1.1.1 整数类型
- 整数类型是没有小数部分的数字,Rust提供了多种整数类型,包括有符号和无符号的8位、16位、32位、64位和128位整数。
- 例如,
u32
表示一个无符号32位整数,范围从0到4294967295。 - 整数的类型可以通过在数字后添加后缀来指定,如
57u8
表示8位无符号整数。 isize
和usize
类型取决于程序运行的计算机架构,表格中用“arch”表示:如果是在 64 位架构上,则为 64 位;如果是在 32 位架构上,则为 32 位。
Length | Signed | Unsigned |
---|---|---|
8-bit | i8 | u8 |
16-bit | i16 | u16 |
32-bit | i32 | u32 |
64-bit | i64 | u64 |
128-bit | i128 | u128 |
arch | isize | usize |
Rust特殊的编写字面量:
Number literals | Example |
---|---|
Decimal | 98_222 |
Hex | 0xff |
Octal | 0o77 |
Binary | 0b1111_0000 |
Byte (u8 Only) | b'A' |
1.1.2 浮点数类型
- Rust有两种浮点数类型:
f32
和f64
,分别表示32位和64位的浮点数。 - 默认情况下,Rust使用
f64
,因为它在现代CPU上与f32
的速度相近,但精度更高。
1.1.3 布尔类型
- 布尔类型只有两个值:
true
和false
,在Rust中用bool
表示。
1.1.4 字符类型
- Rust的字符类型用
char
表示,支持Unicode标量值,可以表示多种语言的字符和符号。 - 字符使用单引号表示,如
'z'
或'?'
。
1.2 复合类型
复合类型可以将多个值组合成一个类型,Rust的两种基本复合类型是元组(Tuple)和数组(Array)。
1.2.1 元组类型
- 元组是将多个不同类型的值组合在一起的固定长度的集合。
- 创建元组的语法为使用括号包裹的逗号分隔的值,例如
let tup: (i32, f64, u8) = (500, 6.4, 1);
。 - 元组的元素可以通过模式匹配进行解构。
1.2.2 数组类型
- 数组是一种固定长度的集合,所有元素必须是同一类型。
- 数组的定义方式为使用方括号包裹的逗号分隔的值,例如
let a = [1, 2, 3, 4, 5];
。 - 数组的类型可以通过指定元素类型和长度来定义,如
let a: [i32; 5] = [1, 2, 3, 4, 5];
。 - 数组的元素可以通过索引访问,例如
let first = a[0];
。 - 如果尝试访问超出数组范围的索引,Rust会在运行时崩溃并提示错误。
2. 类型注解与类型推断
Rust的编译器通常能够根据变量的值和使用方式推断出类型,但在某些情况下,例如从字符串转换为数字时,需要显式添加类型注解。示例代码如下:
let guess: u32 = "42".parse().expect("Not a number!");[14]
如果未提供类型注解,编译器会提示需要更多信息。
3. 整数溢出处理
- Rust在调试模式下会检查整数溢出,导致程序在运行时崩溃。
- 在发布模式下,Rust会进行二进制补码包装,超出范围的值会“回绕”到最小值。
4. 数字运算
Rust支持基本的数学运算,包括加、减、乘、除和取余。示例代码展示了如何在let
语句中使用这些运算:
let sum = 5 + 10;
let difference = 95.5 - 4.3;
let product = 4 * 30;
let quotient = 56.7 / 32.2;
let remainder = 43 % 5;
5. 示例
-
类型注解示例:
fn main() { let guess: u32 = "42".parse().expect("Not a number!"); }
该示例展示了如何使用类型注解来指定变量
guess
的类型为u32
。 -
整数类型示例:
fn main() { let x: (i32, f64, u8) = (500, 6.4, 1); }
这里定义了一个元组
x
,包含不同类型的整数和浮点数。 -
浮点数示例:
fn main() { let x = 2.0; // f64 let y: f32 = 3.0; // f32 }
该示例展示了如何声明浮点数变量,默认类型为
f64
。 -
布尔类型示例:
fn main() { let t = true; let f: bool = false; // with explicit type annotation }
该示例展示了布尔类型的使用,布尔值可以是
true
或false
。 -
字符类型示例:
fn main() { let c = 'z'; let z: char = 'ℤ'; // with explicit type annotation let heart_eyed_cat = '😻'; }
这里展示了如何声明字符类型的变量,Rust的字符类型支持Unicode。
-
数组示例:
fn main() { let a = [1, 2, 3, 4, 5]; }
该示例展示了如何定义一个包含多个整数的数组。
-
访问数组元素示例:
fn main() { let a = [1, 2, 3, 4, 5]; let first = a[0]; let second = a[1]; }
这里展示了如何通过索引访问数组中的元素。
-
无效数组元素访问示例:
use std::io; fn main() { let a = [1, 2, 3, 4, 5]; println!("Please enter an array index."); let mut index = String::new(); io::stdin() .read_line(&mut index) .expect("Failed to read line"); let index: usize = index .trim() .parse() .expect("Index entered was not a number"); let element = a[index]; println!("The value of the element at index {index} is: {element}"); }
此代码编译成功。如果使用
cargo run
运行此代码并输入0
、1
、2
、3
或4
,程序将打印出数组中该索引处的对应值。如果输入超出数组末尾的数字,例如10
,您将看到如下输出:thread 'main' panicked at src/main.rs:19:19: index out of bounds: the len is 5 but the index is 10 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
程序在使用无效值进行索引操作时导致了运行时错误。程序以错误信息退出,并未执行最后的
println!
语句。 -
注意:当你尝试使用索引访问元素时,Rust 会检查你指定的索引是否小于数组长度。如果索引大于或等于长度,Rust 程序就会崩溃。因此,这种检查必须在运行时进行,尤其是在这种情况下,因为编译器无法预先知道用户稍后运行代码时会输入什么值。这是Rust的一个内存安全原则:当用户提供错误的索引时,可能会访问到无效的内存。Rust 通过立即退出而不是允许内存访问并继续运行来保护你免受此类错误的影响。