猜数游戏

这是一个经典的猜数游戏,玩家需要猜出一个随机生成的1到100之间的整数。
用户输入一个猜测的数字,程序会告诉用户猜测的数字是过高、过低还是正确。
玩家需要不断猜测,直到猜对为止。

全部代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
use rand::Rng;
use std::io;
// 增加了另一个 use 声明,从标准库引入了一个叫做 std::cmp::Ordering 的类型到作用域中。
// Ordering 也是一个枚举,不过它的成员是 Less、Greater 和 Equal。
use std::cmp::Ordering;
fn main() {
// 生成一个1-100内的随机数
// cargo add rand (crate)
let secret_number = rand::rng().random_range(1..=100);
println!("secret number is {}", secret_number);
println!("let's play a game!");
loop {
println!("please guess a number between 1 and 100:");
// 获取用户输入的数据
let mut user_guess = String::new();
io::stdin()
.read_line(&mut user_guess)
.expect("Failed to read line");
// let user_guess: u32 = user_guess.trim().parse().expect("Please type a number!");
let user_guess: u32 =match user_guess.trim().parse() {
Ok(num)=>num,
Err(_)=>continue
};

println!("your guess number is {user_guess}!");
// 用户输入和随机数比较
// NOTE: &
match user_guess.cmp(&secret_number) {
Ordering::Greater =>println!("Too big!"),
Ordering::Less =>println!("Too low!"),
Ordering::Equal =>{
println!("You win!");
break;
}
}
}

}

我的代码可能和官方稍有不同,因为我使用了更高版本的rand crate。

1
2
3
4
5
6
7
[package]
name = "guess_game"
version = "0.1.0"
edition = "2024"

[dependencies]
rand = "0.9.2"

知识点

在本节中我们先大概了解这些内容,初步对rust语言有个了解,在后续的课程中会对里面的一些知识点详细讲解。

标准库和 crate

  • rust 使用 use 引入标准库中的模块,例如 std::cmp::Ordering 用于比较两个值的大小关系,std::io 用于处理标准输入输出,rand::Rng 用于生成随机数。
  • std 为标准库的缩写,用于访问标准库中的函数和类型。
  • rand 是一个 crate(包),用于生成随机数。rand是一个非标准库,需要在 Cargo.toml 中添加依赖。使用cargo add rand 可以添加rand crate。或者在 Cargo.toml 中手动添加依赖。
  • crates.io 是一个 Rust 社区维护的 crate 仓库,用户可以在其中查找和分享 Rust 代码。

变量和可变性

  • rust 中的变量默认是不可变的,即一旦绑定了一个值,就不能改变它。例如 let x = 5; 绑定了一个值为5的变量x,之后不能再将x绑定到其他值。
  • 如果需要一个可变的变量,需要使用 mut 关键字。例如 let mut x = 5; 绑定了一个可变的变量x,之后可以将x绑定到其他值。
  • 变量的类型可以在声明时指定,也可以根据赋值的类型自动推断。例如 let x = 5; 中,x的类型被推断为 i32
  • 当然rust也有const关键字,用于定义常量,例如 const X: i32 = 5; 定义了一个值为5的常量X,之后不能再改变它。

变量默认是不可变的,这是rust的一个设计原则,他可以帮助我们避免一些错误。主要作用是用在这种情况:

  • 当我们定义的一个变量后面需要改变数据类型的时候,比如一开始用户输入的数字是一个字符串,但是后面和随机数进行比较我们需要将字符串转换为整数。

其他知识点

  • 生成新的字符串s可以使用 let s = String::new();
  • ::new 那一行的 :: 语法表明 new 是 String 类型的一个 关联函数(associated function)。关联函数是针对某个类型实现的函数,在这个例子中是 String。
  • 代码中的 .read_line(&mut guess) 方法,用来获取用户输入。 将 &mut guess 作为参数传递给 read_line 函数,让其将用户输入储存到这个字符串中。
  • read_line 的工作是,无论用户在标准输入中键入什么内容,都将其追加(不会覆盖其原有内容)到一个字符串中,因此它需要字符串作为参数这个字符串参数应该是可变的,以便 read_line 将用户输入附加上去。
  • & 表示这个参数是一个 引用(reference),它允许多处代码访问同一处数据,而无需在内存中多次拷贝。