rust:猜数字小游戏
猜数字小游戏
我们来实现一个经典的入门级编程小游戏 —— 猜谜游戏。具体玩法是这样的:程序会先在 1 到 100 之间随机选一个整数作为谜底。之后,它会让玩家输入自己的猜测数字。玩家输入后,程序会给出提示:如果猜的数字比谜底大,就说 “太高了”;如果比谜底小,就说 “太低了”。一旦玩家猜对了数字,游戏就会弹出一条祝贺信息,然后结束运行。
新建项目
- 使用Cargo构建一个新项目
输入以下命令构建项目:
cargo new guessing_game

- 用VSCode打开这个项目
项目结构
guessing_game/
├── Cargo.toml # 项目配置文件
└── src/
└── main.rs # 主程序文件
编写小游戏代码
首先玩家先猜测一个数字输入
use std::io;fn main() {println!("请猜一个数字");let mut guess = String::new();io::stdin().read_line(&mut guess).expect("读取失败");println!("您猜的数字是{guess}");
}
- 
use std::io;
 引入std::io模块,这样我们就可以使用io::stdin()来读取用户输入。
- 
fn main() { ... }
 程序的入口函数。
- 
println!("请猜一个数字");
 向控制台输出提示信息。
- 
let mut guess = String::new();- 
let:声明变量。
- 
mut:表示这个变量是可变的(因为我们要往里面写入内容)。
- 
guess:变量名。
- 
String::new():创建一个空的、可增长的字符串(在堆上分配)。
 
- 
- 
io::stdin().read_line(&mut guess).expect("读取失败");- 
io::stdin():获取标准输入流。
- 
.read_line(&mut guess):读取用户输入的一行,并追加到guess字符串中。- &mut guess是对- guess的可变引用,允许- read_line修改它。
 
- 
.expect("..."):处理可能的错误。read_line返回一个Result类型,expect在出错时会 panic 并显示指定消息。
 
- 
- 
println!("您猜的数字是 {guess}");
 使用{}占位符打印guess变量的内容。Rust 会自动将其转换为字符串显示。
测试一下游戏的第一部分,先从控制台运行一下这段代码看看结果:

如果如图所示,说明第一部分已经完成。
生成随机数
Rust在标准库中没有包含随机数的方法,Rust团队提供了一个可以实现随机数功能的rand crate
rand crate 是 Rust 社区中最常用、最权威的随机数生成库(crate),它让你可以轻松地在程序中生成各种类型的随机值,比如随机整数、浮点数、布尔值、字符串、数组元素等。
- crate 是一个独立的代码包(库或可执行程序)。
- rand是一个外部 crate,不在标准库中,所以你需要先在项目中添加它。
- 添加依赖
打开你的项目目录中的 Cargo.toml 文件,在[dependencies]中添加以下代码
rand = "0.8.5"
- 构建项目
在控制台中输入以下命令构建项目:
cargo build

- 代码生成随机数
use std::io;
use rand::Rng;fn main() {let secret_number = rand::thread_rng().gen_range(1..=100);println!("随机数字是{secret_number}");println!("请猜一个数字");let mut guess = String::new();io::stdin().read_line(&mut guess).expect("读取失败");println!("您猜的数字是{guess}");
}use rand::Rng:导入 rand crate 提供的 Rng trait。这是使用 .gen_range() 等随机数方法所必需的。
 let secret_number = rand::thread_rng().gen_range(1..=100);:
- rand::thread_rng():获取当前线程的随机数生成器。
- .gen_range(1..=100):生成一个 1 到 100 之间的随机整数(包含 1 和 100)。
- let secret_number = ...:把这个随机数存到不可变变量- secret_number中(类型通常是- i32或- u32)。
println!("随机数字是{secret_number}");:输出提示,显示生成的随机数。
将猜测的数字和随机生成的数字进行比较
use std::io;
use rand::Rng;
use std::cmp::Ordering;fn main() {let secret_number = rand::thread_rng().gen_range(1..=100);println!("随机数字是{secret_number}");println!("请猜一个数字");let mut guess = String::new();io::stdin().read_line(&mut guess).expect("读取失败");let guess: u32 = guess.trim().parse().expect("请输入一个数字");println!("您猜的数字是{guess}");match guess.cmp(&secret_number){Ordering::Less => println!("太小了"),Ordering::Greater => println!("太大了"),Ordering::Equal => println!("恭喜你,猜对了"),}
}use std::cmp::Ordering;:导入 Ordering` 枚举类型,它是 Rust 标准库中用于比较操作的结果类型。有三个变体:
- Ordering::Less(小于)
- Ordering::Greater(大于)
- Ordering::Equal(等于)
let guess: u32 = guess.trim().parse().expect("请输入一个数字");:
- guess.trim():去掉字符串前后的空白字符(特别是- \n换行符)
- .parse():尝试将字符串解析为数字
- let guess: u32:指定目标类型为- u32(无符号32位整数)
- .expect("..."):如果解析失败(比如用户输入了- abc),程序崩溃并提示“请输入一个数字”
这样 guess 就从 String 变成了 u32 类型,可以和 secret_number 比较了。
match guess.cmp(&secret_number){Ordering::Less => println!("太小了"),Ordering::Greater => println!("太大了"),Ordering::Equal => println!("恭喜你,猜对了"),}
使用 cmp 方法比较用户猜测和神秘数字:
- guess.cmp(&secret_number)返回一个- Ordering枚举值
- 根据结果输出不同提示
- 如果相等(Equal),打印恭喜信息,并执行break,退出loop循环
使用循环语句进行多次猜测以及完善优化
use std::io;
use rand::Rng;
use std::cmp::Ordering;fn main() {let secret_number = rand::thread_rng().gen_range(1..=100);// println!("随机数字是{secret_number}");loop{println!("请猜一个数字");let mut guess = String::new();io::stdin().read_line(&mut guess).expect("读取失败");let guess: u32 = match guess.trim().parse(){Ok(num) => num,Err(_) => {println!("请输入有效数字");continue;}};println!("您猜的数字是{guess}");match guess.cmp(&secret_number){Ordering::Less => println!("太小了"),Ordering::Greater => println!("太大了"),Ordering::Equal => {println!("恭喜你,猜对了");break;}}}
}loop{}:loop 是 Rust 中的无限循环关键字。它会一直执行里面的代码,直到遇到 break。
let guess: u32 = match guess.trim().parse(){Ok(num) => num,Err(_) => {println!("请输入有效数字");continue;}};
这是错误处理的关键部分!
- guess.trim():去掉字符串前后的空白字符(特别是换行符- \n)
- .parse():尝试将字符串解析为- u32类型
- 返回 Result<u32, ParseIntError>
- 使用 match处理结果:- Ok(num):解析成功,返回数字
- Err(_):解析失败(比如输入了- abc),打印提示并执行- continue
- continue:跳过本次循环的剩余部分,重新开始下一次循环,再次提示输入
 
总结
项目功能
| 功能 | 实现方式 | 
|---|---|
| 生成随机数 | rand::thread_rng().gen_range(1..=100) | 
| 读取用户输入 | std::io::stdin().read_line(&mut guess) | 
| 字符串转数字 | .trim().parse()将String转为u32 | 
| 错误处理 | match处理parse()失败,提示用户重新输入 | 
| 多次猜测 | 使用 loop {}实现无限循环 | 
| 比较大小 | 使用 .cmp()和std::cmp::Ordering枚举 | 
| 游戏结束 | 猜中时使用 break跳出循环 | 
核心 Rust 概念掌握
| 概念 | 在项目中的体现 | 
|---|---|
| 变量与可变性 | let mut guess = String::new(); | 
| 数据类型 | String(字符串)、u32(无符号整数) | 
| 函数调用 | read_line()、trim()、parse()、gen_range() | 
| 表达式与语句 | match是表达式,可以返回值 | 
| 模式匹配(match) | 处理 Result和Ordering枚举 | 
| 错误处理 | 使用 match安全处理parse()失败 | 
| 循环控制 | loop+continue/break | 
| 外部依赖(crate) | 使用 randcrate 生成随机数 | 
| 模块系统 | use std::io;、use rand::Rng;、use std::cmp::Ordering; | 
技术栈
- 语言:Rust
- 构建工具:Cargo(自动管理依赖和编译)
- 依赖库:
- rand = "0.8":生成随机数
 
- 标准库模块:
- std::io
 h- 安全处理parse()- 失败 | | **循环控制** |loop- +continue- /break- | | **外部依赖(crate)** | 使用rand- crate 生成随机数 | | **模块系统** |use std::io;- 、use rand::Rng;- 、use std::cmp::Ordering;` |
 
技术栈
- 语言:Rust
- 构建工具:Cargo(自动管理依赖和编译)
- 依赖库:
- rand = "0.8":生成随机数
 
- 标准库模块:
- std::io
- std::cmp::Ordering
 
