概述
本篇博客是对 Rust 官方提供的 a Guessing Game 的代码解读,所有的解读都以注释的形式出现在代码块中,让读者可以了解基本的关键字用法与程序语法。
Reference:https://doc.rust-lang.org/book/ch02-00-guessing-game-tutorial.html
代码
// main.rs
// "//" 是 Rust 中单行注释(comment)的开头
// Rust 只在所有程序中添加少量的名称(https://doc.rust-lang.org/std/prelude/index.html)
// 故如果我们需要一些作用域之外的,需要使用 use 引入
use std::io;
use rand::Rng; // Rust 没有实现随机数,但是其提供了一个 rand Crate;trait Rng 提供了一些随机数生成的实现
use std::cmp::Ordering; // 与 Result 相似,Ordering 也是一个 enum
// fn main() 函数是程序的入口
// () 意味着没有向 main 函数传入参数
// { 是函数体的开头
fn main() {
// println! 是用于打印一行字符串的宏(macro)
println!("Guess the number!");
// gen_range(...) 函数接收一个 range expression
// 1..101 等价于 1..=100
// - 1..101 <=> [1, 101)
// - 1..=100 <=> [1, 100]
let secret_number = rand::thread_rng().gen_range(1..=100);
println!("The secret number is: {}", secret_number);
// loop 关键字 => 死循环
loop {
println!("Please input your guess.");
// 在 Rust 中,使用 let 关键字声明的 variable 默认都是不可变的(immutable)
// 如果希望 variable 可变,可以使用 mut 关键字进行声明
// = 是赋值运算符
// ::new 表示 new 是 String 的相关函数(associated function)
let mut guess = String::new();
// 在文件开头使用 use std::io 后,就可以使用 io 模块中的一些 I/O 函数了
// io::stdin() 函数返回一个 std::io::Stdin 的实例,其负责处理来自终端(Terminal)的输入(Input)
io::stdin()
// read_line(...) 函数的参数是一个可变的字符串引用(&mut)
// & 表示传入引用,使调用函数能直接访问该代码块,而不是进行在内存中进行(多次)复制
.read_line(&mut guess)
// read_line(...) 返回一个类型为 io::Result 的实例
// Rust 中有许多模块都有一个叫做 Result 的类型
// Result 是一种 enumerations(枚举),其有 Ok 与 Err 两个 variants
// - Ok 表示操作成功(在 Ok 中的值是方法返回的值)
// - Err 表示操作出现异常
// expect 方法会导致程序崩溃
// 如果不进行相关处理(例如调用 expect 方法),Rust 会提示一个 warning,表示你未处理一个可能的异常
.expect("Failed to read line.");
// 由于 guess(String)不能与 secret_number(u32)进行比较(类型不一致),
// 故需要先将 guess(String)重新声明为 guess(u32)
// : u32 说明了 guess 的数据类型为 u32
// parse() 方法返回一个 Result
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue, // 下划线 _ 匹配所有的值
};
// println! 中,出现在第一个字符串参数的 {} 代表 placeholder(占位符)
println!("You guessed: {}", guess);
// cmp 函数接收一个引用进行比较,返回一个 Ordering::Greater 实例
// match expression 进行 pattern match(模式匹配)
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Equal => {
println!("You win!");
break; // 当用户输入正确的数时,跳出循环
}
Ordering::Greater => println!("Too big!"),
}
}
}
# cargo.toml
[package]
name = "guessing_game"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rand = "0.8.3"