书里是第2章内容,不过我在看完前11章后,才回过头来看。
02.1 原始代码
书里的代码是比较简单的:
use std::io;
use rand::Rng;
use std::cmp::Ordering;
fn main() {
println!("Guess the number!");
let secret_number = rand::thread_rng().gen_range(1..=100);
println!("The secret number is: {secret_number}");
loop{
println!("Please input your guess.");
let mut guess = String::new();
io::stdin().read_line(&mut guess)
.expect("Failed to read line");
let guess: u32 = match guess.trim().parse::<u32>() {
Ok(num) => num,
Err(_) => {
println!("Please type a number!");
continue;
}
};
println!("You guessed: {guess}");
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
println!("You win!");
break;
}
}
}
}
虽然比较简单,还是有些要避坑的注意点:
- 与书上不太一样,
match str.parse()
是不行的,因为parse
返回没有指定类型,需要使用parse::<u32>
明确类型 match
对应的匹配符号是=>
,我写成了:
,找问题时还反应不过来,找了半天才找到。- 使用
rand
模块时,从镜像拉取库失败,最后安装了一个crm
,使用官方镜像才成功。 - 生成随机数时,
gen_range(1..=100)
意思是从1
到100
,包含100
,如果没有=
意思是不包括100
。
02.2 优化
作为一名成熟的程序员,已经学了后面几章,当然不满足于此。
封装guess
模块和 Guess
结构:
// guess.rs
use std::cmp::Ordering;
use std::fmt;
#[derive(Debug)]
pub struct Guess{
value: u32,
}
impl Guess{
pub fn new(v: u32)-> Result<Guess, String>{
if v < 1 || v > 100 {
Err("Invalid input value, please input value between 1 and 100!".to_string())
} else {
Ok(Guess{value: v})
}
}
pub fn from_str(v: &str) -> Result<Guess, String>{
let value = match v.trim().parse::<u32>() {
Ok(value) => value,
Err(_) => return Err("Please type a number!".to_string())
};
Self::new(value)
}
pub fn cmp(&self, secret_num: u32) -> Ordering {
return self.value.cmp(&secret_num)
}
pub fn check(&self, secret_num: u32) -> Result<String, String> {
match self.cmp(secret_num) {
Ordering::Less => Err("Too small".to_string()),
Ordering::Greater => Err("Too big!".to_string()),
Ordering::Equal => Ok("You win!".to_string()),
}
}
}
impl fmt::Display for Guess{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result{
write!(f, "Your guess is: {}", self.value)
}
}
main
改为调用模块:
use std::io;
use rand::Rng;
mod guess;
use guess::Guess;
fn main() {
println!("Guess the number!");
let secret_number = rand::thread_rng().gen_range(1..=100);
println!("The secret number is: {secret_number}");
loop{
println!("Please input your guess.");
let mut guess = String::new();
io::stdin().read_line(&mut guess)
.expect("Failed to read line");
let guess = match Guess::from_str(&guess) {
Ok(guess) => guess,
Err(msg) => {
println!("{}", &msg);
continue;
}
};
println!("{}", guess);
match guess.check(secret_number) {
Err(msg) => println!("{msg}"),
Ok(msg) => {
println!("{msg}");
break;
}
}
}
}
基本将之前能使用的技术都用了一遍。
模块、trait
、Result
等。
- 打赏
- 分享
分享到...
请选择打赏方式
- 微信
- 支付宝