返回
创建于
状态
公开
学习 Rust 的基础语法和数据类型是一个循序渐进的过程。让我们一步步梳理关键点,并通过示例加深理解:
1. 变量绑定与可变性
- 不可变变量:默认变量不可变,确保安全性。
1let x = 5; 2// x = 6; // 错误!x 不可变 - 可变变量:使用
mut显式声明可变性。1let mut y = 5; 2y = 6; // 正确
2. 基本数据类型
整数类型
- 有符号 (
i8,i16,i32,i64,i128,isize) 和无符号 (u8,u16, ...)。1let a: i32 = -42; 2let b: u64 = 100;
浮点类型
f32和f64,默认f64。1let x = 3.14; // f64 2let y: f32 = 2.718;
布尔与字符
bool类型:true或false。char类型:4 字节 Unicode 标量值。1let is_active = true; 2let emoji = '🚀';
3. 复合类型
元组 (Tuple)
- 固定长度,可包含不同类型。
1let tup: (i32, f64, char) = (500, 6.4, '🔥'); 2let (x, y, z) = tup; // 解构 3println!("y = {}", y); // 6.4
数组 (Array)
- 固定长度,元素类型相同。
1let arr = [1, 2, 3, 4, 5]; 2let first = arr[0]; // 1
4. 控制流
if 表达式
- 条件必须为
bool类型。1let number = 6; 2if number % 2 == 0 { 3 println!("偶数"); 4} else { 5 println!("奇数"); 6}
循环
-
loop:无限循环,需手动退出。1let mut count = 0; 2loop { 3 count += 1; 4 if count > 3 { break; } 5} -
while:条件循环。1let mut count = 0; 2while count < 3 { 3 count += 1; 4} -
for:遍历集合。1let arr = [10, 20, 30]; 2for elem in arr.iter() { 3 println!("值: {}", elem); 4}
match 模式匹配
- 必须覆盖所有可能情况。
1let value = 3; 2match value { 3 1 => println!("一"), 4 2 | 3 => println!("二或三"), 5 _ => println!("其他"), 6}
5. 所有权与借用
所有权规则
- 每个值有且只有一个所有者。
- 所有者离开作用域,值被丢弃。
1let s1 = String::from("hello"); 2let s2 = s1; // s1 的所有权转移给 s2 3// println!("{}", s1); // 错误!s1 不再有效
借用(引用)
-
不可变引用:允许多个只读引用。
1let s = String::from("hello"); 2let r1 = &s; 3let r2 = &s; // 允许 -
可变引用:同一时间只能有一个。
1let mut s = String::from("hello"); 2let r = &mut s; 3// let r2 = &mut s; // 错误!已有可变引用
6. 错误处理
Result 与 Option
-
Option<T>:表示值可能存在 (Some) 或不存在 (None)。1fn find_even(arr: &[i32]) -> Option<i32> { 2 for &num in arr { 3 if num % 2 == 0 { 4 return Some(num); 5 } 6 } 7 None 8} -
Result<T, E>:表示操作可能成功 (Ok) 或失败 (Err)。1use std::fs::File; 2 3fn open_file() -> Result<File, std::io::Error> { 4 File::open("hello.txt") 5}
错误处理方式
-
match处理:1let result = File::open("hello.txt"); 2match result { 3 Ok(file) => println!("文件已打开"), 4 Err(e) => println!("打开失败: {}", e), 5} -
unwrap和expect:快速解包,失败时 panic。1let file = File::open("hello.txt").unwrap(); 2let file = File::open("hello.txt").expect("打开文件失败"); -
?操作符:传播错误。1fn read_file() -> Result<String, std::io::Error> { 2 let mut s = String::new(); 3 File::open("hello.txt")?.read_to_string(&mut s)?; 4 Ok(s) 5}
7. 练习示例
任务:编写函数,接收整数数组,返回所有偶数的和。处理空结果。
1fn sum_evens(arr: &[i32]) -> Option<i32> {
2 let sum: i32 = arr.iter()
3 .filter(|&&x| x % 2 == 0)
4 .sum();
5 if sum == 0 { None } else { Some(sum) }
6}
7
8fn main() {
9 let nums = [1, 2, 3, 4, 5];
10 match sum_evens(&nums) {
11 Some(s) => println!("偶数和: {}", s),
12 None => println!("无偶数"),
13 }
14}输出:
1偶数和: 6常见问题与解决
-
所有权错误:尝试使用已移动的值。
- 解决:使用引用 (
&) 或克隆 (clone())。
- 解决:使用引用 (
-
类型不匹配:函数返回类型与实际值不符。
- 解决:检查返回类型,使用
Ok/Some或调整类型。
- 解决:检查返回类型,使用
-
借用冲突:同时存在可变和不可变引用。
- 解决:确保作用域不重叠。
通过逐步练习和查阅错误信息,可以深入理解 Rust 的特性和设计哲学。