feat(part2): 添加Rust基础练习项目

新建part2项目,包含Cargo.toml和Cargo.lock配置文件,以及Rust基础语法练习代码。
包括变量类型、流程控制、函数定义等练习内容,用于巩固Rust编程基础。
This commit is contained in:
Yuhang Wu 2026-07-07 15:38:32 +08:00
parent f9eb35c1e0
commit 8a87daba0b
3 changed files with 207 additions and 0 deletions

7
part2/Cargo.lock generated Normal file
View File

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "part2"
version = "0.1.0"

6
part2/Cargo.toml Normal file
View File

@ -0,0 +1,6 @@
[package]
name = "part2"
version = "0.1.0"
edition = "2024"
[dependencies]

194
part2/src/main.rs Normal file
View File

@ -0,0 +1,194 @@
// ============================================================
// Rust 基础巩固练习 (变量类型 + 流程控制)
// 在做完所有题目之前,建议先注释掉 main 函数中的代码,
// 每题单独写一个函数来测试,然后在 main 中调用。
// ============================================================
fn main() {
println!("Hello, world!");
// ex1_variables();
// ex2_scalar_types();
ex3_compound_types();
}
// ============================================================
// 练习1变量与可变性
// ============================================================
// 1. 声明一个不可变变量 x = 10尝试修改它为 20看编译器报什么错
// 然后把报错的那行注释掉。
// 2. 声明一个可变变量 y = 5然后将它修改为 15打印修改前后的值。
// 3. 使用 let 遮蔽shadowing声明变量 z = "hello"
// 然后用 let 再次声明 z将其值改为 z.len()(即字符串长度),
// 再用 let 声明 z将其值改为 z * 2。打印每次遮蔽后的值。
#[allow(dead_code)]
fn ex1_variables() {
// TODO: 在这里写你的代码
let x = 10;
// error: could not compile `part2` (bin "part2") due to 1 previous error; 10 warnings emitted
// x = 20;
let mut y = 5;
println!("修改前:{}", y);
y = 15;
println!("修改后:{}", y);
let z = "hello";
println!("z:{}", z);
let z = z.len();
println!("z:{}", z);
let z = z * 2;
println!("z:{}", z);
}
// ============================================================
// 练习2基本数据类型
// ============================================================
// 1. 声明 u8, i32, f64, bool, char 类型的变量各一个,赋予合理的值。
// 2. 使用 as 关键字将 u8 转换为 i32将 f64 转换为 i32观察小数部分被截断
// 3. 打印字符 char 的数值表示(用 as u32
// 4. 声明一个 usize 变量 = 5让它减去 10观察 underflow 的编译报错或用 wrapping_sub
#[allow(dead_code)]
fn ex2_scalar_types() {
// TODO: 在这里写你的代码
let u8_var: u8 = 42;
let i32_var: i32 = 128;
let f64_var: f64 = 3.14;
let char_var = '2';
println!("u8 as i32: {}", u8_var as i32);
println!("f64 as i32: {}", f64_var as i32);
println!("char as u32: {}", char_var as u32);
let usize_var: usize = 5;
// error: usize_var - 10: attempt to compute `5_usize - 10_usize`, which would overflow
// usize_var.wrapping_sub(10): 18446744073709551611
println!("usize_var - 10: {}", usize_var.wrapping_sub(10));
}
// ============================================================
// 练习3复合类型 —— 元组 (Tuple) 和数组 (Array)
// ============================================================
// 1. 声明一个元组 tup: (i32, f64, &str) = (42, 3.14, "rust")
// 分别用解构和 .索引 两种方式取出并打印三个元素。
// 2. 声明一个数组 arr: [i32; 5] = [1, 2, 3, 4, 5]
// 用 for 循环遍历打印每个元素,打印数组长度。
// 3. 尝试访问 arr[10],观察编译报错 vs 运行时 panic 的区别——
// 先用常量索引(编译期检查),再用变量索引(运行期检查)。
#[allow(dead_code)]
fn ex3_compound_types() {
// TODO: 在这里写你的代码
let tup: (i32, f64, &str) = (42, 3.14, "rust");
let (a, b, c) = tup;
println!("tup: {}, {}, {}", a, b, c);
let a1 = tup.0;
let b1 = tup.1;
let c1 = tup.2;
println!("tup: {}, {}, {}", a1, b1, c1);
}
// ============================================================
// 练习4函数定义与调用
// ============================================================
// 1. 写一个函数 add(a: i32, b: i32) -> i32返回两数之和在 main 中调它。
// 2. 写一个函数 factorial(n: u32) -> u32用循环计算 n 的阶乘。
// 提示n! = 1 × 2 × 3 × ... × n0! = 1
// 3. 写一个函数 is_even(n: i32) -> bool判断一个数是否为偶数。
// 4. 写一个无返回值的函数 greet(name: &str),打印 "你好,{name}"。
#[allow(dead_code)]
fn add(a: i32, b: i32) -> i32 {
// TODO
0
}
#[allow(dead_code)]
fn factorial(n: u32) -> u32 {
// TODO
0
}
#[allow(dead_code)]
fn is_even(n: i32) -> bool {
// TODO
false
}
#[allow(dead_code)]
fn greet(name: &str) {
// TODO
}
fn ex4_functions() {
// 在这里调用上面四个函数进行测试
}
// ============================================================
// 练习5控制流 —— if / else if / else
// ============================================================
// 1. 写一个函数 grade(score: u32) -> &'static str根据分数返回等级
// 90-100 → "A", 80-89 → "B", 70-79 → "C", 60-69 → "D", 0-59 → "F"
// 2. 写一个函数 fizzbuzz(n: u32),打印 1 到 n
// 能被 3 整除打印 "Fizz",能被 5 整除打印 "Buzz"
// 能同时被 3 和 5 整除打印 "FizzBuzz",否则打印数字本身。
// 3. 使用 if 作为表达式let x = if ... { ... } else { ... };
// 根据一个 bool 变量给另一个变量赋不同的值。
#[allow(dead_code)]
fn grade(score: u32) -> &'static str {
// TODO
"F"
}
#[allow(dead_code)]
fn fizzbuzz(n: u32) {
// TODO
}
fn ex5_control_flow() {
// 在这里测试
}
// ============================================================
// 练习6循环 —— loop / while / for
// ============================================================
// 1. 用 loop 写一个无限循环,内部用计数器从 1 开始累加,
// 当计数达到 100 时用 break 退出,并用 break 返回值打印最终结果。
// 2. 用 while 循环打印 10 到 1 的倒数。
// 3. 用 for 循环遍历一个数组 [10, 20, 30, 40, 50],打印每个元素及其索引。
// 提示:用 .iter().enumerate()
// 4. 用 for 循环配合 Range打印 1..=5 的每个数的平方。
#[allow(dead_code)]
fn ex6_loops() {
// TODO: 在这里写你的代码
}
// ============================================================
// 练习7综合猜数字游戏简化版
// ============================================================
// 写一个函数 mini_guessing_game(),模拟一个简化的猜数字游戏:
// - 设定一个固定的秘密数字(比如 42
// - 用一个数组 [10, 50, 35, 60, 42] 模拟玩家的猜数字序列
// - 遍历数组,对每次猜测判断:
// - 猜小了 → 打印 "{} 太小了!"
// - 猜大了 → 打印 "{} 太大了!"
// - 猜对了 → 打印 "{} 猜对了!" 并退出循环
// 提示for + if/else + break
#[allow(dead_code)]
fn mini_guessing_game() {
// TODO: 在这里写你的代码
}
// ============================================================
// 练习8综合统计字符串中的字母
// ============================================================
// 写一个函数 count_letters(s: &str) -> (u32, u32),接收一个字符串切片,
// 统计其中大写字母和小写字母的数量,以元组形式返回。
// - 提示1用 .chars() 获取字符迭代器
// - 提示2用 char::is_uppercase() 和 char::is_lowercase() 判断
// - 提示3在 ex8_stats 中调用这个函数,用两个不同的字符串测试
#[allow(dead_code)]
fn count_letters(s: &str) -> (u32, u32) {
// TODO
(0, 0)
}
fn ex8_stats() {
// 在这里测试 count_letters
}