标题
- 一、从源码中学习
- 1.1 源码
- 1.2 运行结果
- 二、 导入一个trait
- 三、重要源码分析
一、从源码中学习
1.1 源码
一个简单的猜数大小游戏,不集的输入,直到猜测正确时退出。
use rand::Rng;
use std::cmp::Ordering;
use std::io;
fn main() {
let secret_number = rand::thread_rng().gen_range(1, 101);
// println!("神秘数字是: {}", secret_number);
loop {
println!("猜测一个数[1,100]:");
let mut guess = String::new();
//把输入放到guess字符串中
io::stdin().read_line(&mut guess).expect("无法读取行");
let guess: u32 = match guess.trim().parse(){
Ok(num1) => num1,
Err(message) => {
println!("错误: {message}!");
continue;
}
};
// println!("您猜测的数是: {}", guess);
match guess.cmp(&secret_number) {
Ordering::Less => println!("太小了!"),
Ordering::Greater => println!("太大了!"),
Ordering::Equal => {
println!("赢麻了_^_!");
break;
}
}
}
}
1.2 运行结果
二、 导入一个trait
该程序需要引用第三方随机数库,打开Cargo.toml
文件,在[dependencies]
下添加一行rand = "0.3.14"
,也可以写成rand = ^0.3.14
,前者是后者的简写,表示任何至少是 0.3.14 但小于 0.4.0 的版本。
三、重要源码分析
- 类似于python中的import导入第三方包,Rust需要使用use导入它所需要使用的
随机数
,Ordering枚举
以及io操作
库。
use rand::Rng;
use std::cmp::Ordering;
use std::io;
- Rng 是一个 trait,它定义了随机数生成器应实现的方法,代码中调用了
rand::thread_rng
函数提供实际使用的随机数生成器:它位于当前执行线程的本地环境中,并从操作系统获取种子,接着调用随机数生成器的 gen_range 方法,可以使用start..=end
的方式来包含上下端,也可以使用代码中的方式,两者都表示生成[1,100]
中的随机数。
let secret_number = rand::thread_rng().gen_range(1, 101);
- Rust使用
let
定义变量,默认的变量为不可变变量,例如下面的语句会报错
let x = 1;
x = 3; //Error: cannot assign twice to immutable variable
要解决这个问题,需要添加mut
关键字
let mut x = 1;
x = 3; //Right
- 由于需要向一串表示字符串的地址中写入数据,因此将指向该地址的变量定义为mut类型,使用
String::new()
申请一串地址空间,该空间是一个UTF8编码的可增长文本块,可以将该函数理解成c++中的静态方法。 - 从标准输入(键盘,即stdin)中读取字符串并存入申请的内存地址中,注意:read_line的工作原理是:无论用户在标准输入中输入什么内容,都会追加到一个字符串中,因此不能把
String::new()
函数写到loop
外面,因为这样写会每次都追加数据(包括回车符)
,导致程序出错。 - 从键盘输入的为字符串,因此要使用
let guess: u32
强制将输入的字符串转换为32位无符号整数,以此与生成的整数进行比较。 -
trim()
取消输入字符两边的空格和换行符,parse()
转换为整数,如果转换成功返回Ok
和最终的值,否则返回Err
和错误信息,因此将返回值进行处理。
let guess: u32 = match guess.trim().parse(){
Ok(num1) => num1,
Err(message) => {
println!("错误: {message}!");
continue;
}
};
- 最后将输入的值与生成的值进行对比分析,指引用户逐渐输入正确的值。