通过猜谜游戏了解Rust
1.建立新工程
cargo new guessing_game
cd guessing_game
建立新的猜谜游戏文件夹、进入到这个文件夹中。
2.编写原始CODE
- 通过src/main.rs进入程序文件
- 对文件进行修改
- 首先读取标准输入输出流文件,
- 语法为
use std::io;
- 此处需要有结尾标点符号;,
- 接着编写主函数:
fn main() { println!("Guess the number!"); println!("Please input your guess!"); let mut guess = String::new(); io:stdin() .read_line(&mut guess) .expect("Failed to read line"); println!("your guessed :{guess}"); }
- 到这里时,需要明确一些语法结构:
println!("You guessed: {guess}");
- 可以用C语言来对比,
println!("You guessed:{}",guess)
println!("x = {} and y = {}", x, y);
- 这些都是合法的println!语句,同时,他又兼具C++的一些特性,比如
std::io::stdin()
(如果前面没有使用use std::io
,可以这样写):
std::io::stdin() { .read_line(&mut guess).expect("Failed to read the line!"); }
.read_line(&mut guess )
和.expect("")
可以分开写,也可以连起来写
let mut guess = String::new();
此处定义中由于RUST默认下:
let x=7;
let j=5;
这些数是const,不能够被改变,因此需要添加mut使其成为可变值。
String::new()则是定义了字符串中一个新的空的字符串。
``
let mut guess = String::new();
整句话的意思就是说定义可变的空的字符串变量guess。
io::stdin()
{
.read_line(&mut guess)
.expect("Failed to read the line");
}
这两句话则是从io模块中取出来stdin函数,再从这个函数中取出来
.read_line(&x) 和 .expect("")
第一个函数则是为了从键盘输入参数,类似于matlab中的input()、C语言中的scanf()
而.expect()则是在.read_line(&x)不能够正常录入时结束程序,这种语句是在前一句正常执行的时候不动,不能执行的时候才用。
编写随机数
rand crate
rust基本函数中不提供rand箱,所以我们需要自己添加rand 箱
在自己的项目中找到cargo.toml,在其中的[dependencies]
依赖包中添加:
rand = "0.8.3"
然后使用cargo build命令进行重新编辑,这时候会自动添加rand对应版本文件,同时会自动添加rand相关依赖包文件。
0.8.3是指不低于0.8.3但同时不超过0.9.0
cargo build在检测到已经安装rand箱后不会继续重新安装,这是他的一个特点。
使用cargo update进行更新时,rand的包仍会遵循之前所设置标准.
形成随机数
use std::io;
use rand::Rng;
fn main()
{
println!("Guess the number!");
let secret_number
= rand::thread_rng().gen_range(1..=100);
println!("the secret number is :{secret number}");
println!("Please input your guess.");
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
println!("You guessed :{guess}");
}
其中,rand::thread_rng()提供了我们特定的随机数生成器,而gen_range(1..=100)则是提供了这个随机数的生成范围。
将输入值和随机数进行比对
use rand::Rng
use std::io
use std::cmp::ordering
fn main()
{
println!("You guessed:{guess}");
match guess.cmp(&secret_number)
{
Ordering::Less=>println!("Too small!");
Ordering::Greater=>println!("Too big!");
Ordering::Equal=>println!("You win!");
}
}
match函数是将值对应起来,而cmp函数和ordering对应,将值进行比较,对号入座。
但是这段代买中有问题,因为secret_number 是一个32bit的number,而mut guess则是一个字符串,而这无法比较。
所以接下来操作则是将guess进行转换。
let guess: u32 = guess.trim().parse().expect("Please type a number!");
在rust中,guess可以直接将旧值和新值通过这种方式替换,前提是guess是可变的。
在字符串中输入字符串的话,会有空格出现,而.trim()是将其中的空格去掉,将其中的\r\n消除,因为在键入过程中会出现使用ENTER会换行,变换到新的行数。
之后出现的.parse()则是在函数中和前面的let guess: u32对应,将字符串转换为u32格式。
循环游戏
添加循环loop{}
,同时在胜利时添加break;
同时处理输入数据,而不是再输入数据错误时退出。
use std::io
use rand::Rang
use std::cmp::ordering
fn main()
{
println!("Guess the number!");
let secret_number = rand::thread_rng().gen_range(1..=100);
loop
{
println!("Please input your guess!");
let mut guess = String::new();
let guess: u32 = match guess.trim().parse()
{
Ok(num)=>num;
Err(_)=>continue;
}
println!("You guessed:{guess}");
match guess.cmp(&secret_number)
{
Ordering::Less=>println!("Tool small!"),
Ordering::Greater=>println!("Too big!"),
Ordering::Equal=>{
println!("You win!");
break;
}
}
}
}
其中match函数跟上一句一样,上一句时cmp(&secret_number){
Ordering::Less
// --snip--
}
这里是因为.parse()函数会发出result,并且result结果只有Ok和Err,而match将其对号入座,如果正确处理,则Ok(num)=>num,
错误则
Err(_)=>continue; 中"_"是包含所有错误值。
总结
这个猜谜游戏中让我基本上了解了RUST的语法结构,本节使用了:
use std::io::stdin
.read_line(&x)
.expect("xxx");
use rand::Rng
rand::thread_rng().gen_range(1..=100);
use std::cmp::ordering
match a.cmp(&b){
Ordering Less=>{}
Ordering Greater=>println!("xxx"),
Ordering Equal=>println!("xxx"),
}
浏览文档说明
cargo doc --open
使用此语句可以进行cargo doc帮助文档建立并进入文档,这种情况只能用于非官方文档,官方文档在链接: [link](https://rustwiki.org/docs/)。