1.数据类型
rust
fn main() {
// 1. 基本标量类型
let count: i32 = 100; // 整数 i32
let price = 59.99; // 浮点数 f64 (默认)
let is_active: bool = true; // 布尔值
let index: usize = 3; // 用于索引
// 2. 固定集合:数组
let scores = [90, 85, 95, 78]; // 数组 [i32; 4]
println!("第 {} 个分数: {}", index, scores[index]); // 使用 usize 访问
// 3. 可变集合:Vector (动态数组)
let mut names: Vec<String> = Vec::new(); // 声明一个可变的 Vector
names.push(String::from("Alice"));
names.push(String::from("Bob"));
// 4. 字符串类型
let name_str: &str = "Charlie"; // 字符串切片 (&str)
let mut welcome_msg = String::from("Hello "); // 可变 String
welcome_msg.push_str(name_str); // String 可以修改
println!("名字列表: {:?}", names);
println!("完整信息: {}", welcome_msg);
}
1) 标量类型
- 整数类型
- 有符号 (Signed),可以是负数或正数。前缀是 i。,"i8,i16,i32,i64,i128"
- 无符号 (Unsigned),只能是零或正数。前缀是 u。,"u8,u16,u32,u64,u128"
- 架构相关,大小取决于运行程序的 CPU 架构(32位或64位)。,"isize, usize (主要用于集合索引或内存大小)"
rust
let x: i32 = 42; // 明确指定 i32
let y = 100; // 默认为 i32
let index: usize = 5; // 常用作索引
let byte: u8 = 255; // 无符号字节
- 浮点数类型
- f64,双精度浮点数(64 位)。,默认类型,精度更高。
- f32,单精度浮点数(32 位)。,速度更快,但精度较低。
rust
let pi = 3.1415926535; // 默认为 f64
let e: f32 = 2.71828; // 明确指定 f32
- 布尔类型
布尔类型只有两个可能的值:true 和 false。
rust
let is_rust_awesome: bool = true;
let is_raining = false; // 默认为 bool
- 字符类型
Rust 的字符类型 char 比许多其他语言的字符类型更强大,因为它支持 Unicode 标量值。
- 大小: 字符类型固定占用 4 字节(32 位),可以表示所有 Unicode 字符(包括表情符号、中文字符等)。
- 表示: 使用单引号 ' '。
rust
let heart_eye = '😍';
let z = 'Z';
let chinese_char: char = '汉';
2) 复合类型
- 元组
元组是一种将固定数量的不同类型的值组合在一起的方式。
- 特点: 长度固定,可以包含不同类型的值。
- 定义: 使用圆括号 ()。
rust
// 定义一个包含 i32, f64, u8 的元组
let person_data: (i32, f64, u8) = (30, 6.2, 180);
// 1. 通过模式匹配解构元组 (推荐)
let (age, height, weight) = person_data;
println!("Age: {}", age); // 输出: 30
// 2. 通过索引访问元素
let height_val = person_data.1; // 索引从 0 开始
println!("Height: {}", height_val); // 输出: 6.2
- 数组
数组是一种将固定数量的相同类型的值组合在一起的方式。
- 特点: 长度固定(定义后不能改变),元素必须是相同类型。
- 定义: 使用方括号 []。
rust
// 定义一个包含 5 个 i32 元素的数组
let numbers: [i32; 5] = [10, 20, 30, 40, 50];
// 访问元素
let first = numbers[0]; // 输出: 10
// 初始化一个包含相同值的数组
let zeros = [0; 8]; // 创建一个包含 8 个 0 的数组:[0, 0, 0, 0, 0, 0, 0, 0]
// 数组越界:在 Rust 中,如果访问的索引超出了数组长度,
// 会在运行时触发 Panic(程序崩溃),而不是像 C/C++ 那样导致未定义行为。
// println!("{}", numbers[5]); // <-- 运行时会 Panic
3) 补充类型
- 字符串
Rust 有两种主要的字符串类型:
- &str (字符串切片): 编译时已知大小的字符串引用(通常是只读的,存储在二进制文件或堆栈中)。它是最常用的字符串类型。
- String (可变字符串): 存储在堆上的动态、可增长、可变的字符串。类似于 Java 的 String 或 C++ 的 std::string。
rust
let name_str: &str = "Charlie"; // 字符串切片 (&str)
let mut welcome_msg = String::from("Hello "); // 可变 String
- 向量
Vec: 动态数组,存储在堆上。与数组不同,它的长度可变,是 Rust 中最常用的集合类型。类似于 Java 的 ArrayList。
rust
let mut names: Vec<String> = Vec::new(); // 声明一个可变的 Vector
names.push(String::from("Alice"));
names.push(String::from("Bob"));
2.函数
rust
// --------------------------------------------------------------------------
// 示例 1: 基础函数 (Basic Function)
// - 不带参数,不带返回值
// - 使用 fn 关键字定义
// --------------------------------------------------------------------------
fn greet() {
println!("Hello, Rust learner!");
}
// --------------------------------------------------------------------------
// 示例 2: 带参数的函数 (Function with Parameters)
// - 必须显式声明参数的类型
// --------------------------------------------------------------------------
fn add_numbers(a: i32, b: i32) {
let sum = a + b;
println!("{} + {} = {}", a, b, sum);
}
// --------------------------------------------------------------------------
// 示例 3: 带返回值的函数 (Function with Return Value)
// - 返回类型必须在 -> 后面声明
// - 函数体中,最后一个表达式的值将作为返回值
// - 注意:返回表达式末尾没有分号 (;)
// --------------------------------------------------------------------------
fn multiply(x: i32, y: i32) -> i32 {
// 这是一个表达式,它的值 (x * y) 就是返回值
x * y
// 如果加上分号,它就变成了语句,返回 () (空元组),导致类型错误:
// x * y; // <-- 错误!
}
// --------------------------------------------------------------------------
// 示例 4: 带有语句和表达式的复杂函数 (Statements vs Expressions)
// - 语句 (Statement): 执行动作但不返回值的代码 (如 let 绑定)
// - 表达式 (Expression): 有返回值,可以用于赋值
// --------------------------------------------------------------------------
fn calculate_area(width: i32, height: i32) -> i32 {
// 语句:声明一个变量绑定,不返回值
let area = {
// 这是一个块表达式 (Block Expression)
let w = width; // 语句
let h = height; // 语句
w * h // 表达式,此块返回 w * h 的值
}; // 块表达式末尾带了分号,所以整个 let area = ... 是一个语句
// 表达式:最后一个表达式的值作为整个函数的返回值
area
}
// --------------------------------------------------------------------------
// 示例 5: 返回元组 (Tuple Return) - 用于返回多个值
// --------------------------------------------------------------------------
fn get_user_info() -> (String, i32) {
let name = String::from("Ferris");
let age = 8;
// 返回一个包含 String 和 i32 的元组
(name, age)
}
// --------------------------------------------------------------------------
// 示例 6: 接收引用 (&) 参数 - 避免所有权转移 (Borrowing)
// - 这是 Rust 函数中最常用的模式
// --------------------------------------------------------------------------
fn print_string_length(s: &String) -> usize {
// 传入的是引用,函数结束后 s 的所有权仍在 main 函数中
s.len()
}
// --------------------------------------------------------------------------
// 主函数:程序的入口点
// --------------------------------------------------------------------------
fn main() {
// 1. 调用基础函数
greet();
// 2. 调用带参数的函数
add_numbers(15, 7);
// 3. 调用带返回值的函数
let result = multiply(6, 9);
println!("6 乘以 9 等于: {}", result);
// 4. 调用带有语句和表达式的函数
let rect_area = calculate_area(10, 5);
println!("矩形面积是: {}", rect_area); // 输出: 50
// 5. 调用返回元组的函数,并解构
let (user_name, user_age) = get_user_info();
println!("用户信息: 名字={}, 年龄={}", user_name, user_age);
// 6. 调用接收引用的函数
let my_string = String::from("RustLang");
// 注意:my_string 的所有权仍然在 main 中
let length = print_string_length(&my_string);
println!("字符串 '{}' 的长度是: {}", my_string, length);
// 验证:my_string 仍然可用,因为传入的是引用
println!("Original string is still here: {}", my_string);
}
3.控制流
条件判断:if 表达式
A. 基本 if/else
rust
fn main() {
let number = 6;
if number % 4 == 0 {
println!("数字可被 4 整除");
} else if number % 3 == 0 {
println!("数字可被 3 整除"); // 6 是 3 的倍数,执行这里
} else if number % 2 == 0 {
println!("数字可被 2 整除");
} else {
println!("数字不能被 4、3 或 2 整除");
}
}
B. 将 if 用作表达式(返回值)
rust
fn main() {
let condition = true;
// 整个 if/else 块返回一个值,赋值给 number
let number = if condition {
5 // 表达式 A,类型是 i32
} else {
6 // 表达式 B,类型也是 i32
// 如果这里返回 "six",则会编译错误,因为类型不匹配
};
println!("数字是: {}", number); // 输出: 5
}
循环结构 (Loop Constructs)
A. loop:无限循环和返回值
rust
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
// 当满足条件时,使用 break 退出循环,并返回 10 * 2
break counter * 2;
}
};
println!("循环的结果是: {}", result); // 输出: 20
}
B. while:条件循环
rust
fn main() {
let mut number = 3;
while number != 0 {
println!("{}!", number);
number -= 1;
}
println!("LIFTOFF!!!");
}
C. for:遍历集合
rust
fn main() {
let a = [10, 20, 30, 40, 50];
// for 循环安全地遍历数组中的每个元素
for element in a.iter() {
println!("当前元素值是: {}", element);
}
}
fn main() {
// 遍历从 1 到 4 的数字(不包含 5)
for number in 1..5 {
println!("数字: {}", number);
}
// 如果要包含 5,使用 1..=5
}
match 匹配
rust
// 匹配数字
fn main() {
let finger_count = 5;
match finger_count {
1 => println!("一个手指"),
2 | 3 => println!("两三个手指"), // 匹配多个值
4..=10 => println!("四到十个手指"), // 匹配范围
_ => println!("不是 1-10 范围内的数字"), // 默认匹配,必须覆盖所有其他情况
}
}
rust
// 匹配 Option<T> (处理可能缺失的值)
fn main() {
let some_number: Option<i32> = Some(42);
match some_number {
// 匹配 Some(value),将 42 赋值给 x
Some(x) => println!("找到了数字: {}", x),
// 匹配 None,处理缺失的情况
None => println!("没有找到任何数字"),
}
}