Rust第三天,编写一个猜数字游戏(第二部分)

上一节我们写到了随便猜一个数字在shell控制台都会打印出结果,但是这样的程序逻辑是不正确的,然后我们继续完善这个功能。

1. 生成秘密数字

在生成秘密数字的时候我们需要用到,rand crate这个库,然而这个库是我们0.8.6才发布的所以我们需要统一一下版本。

1.2 更新箱子以获取新版本

这里我们需要将版本确定一下,就需要修改Cargo.toml文件,修改为如下内容:

ini 复制代码
[package]
name = "guessing_game"
version = "0.1.0"
edition = "2024"

[dependencies]
rand = "0.8.5"

[dependencies] rand = "0.8.5"是我们需要修改的内容,目的是为了和教程中的rand版本一致,因为Rust也有很多版本,随着时间的增长而更新。就好比我们的node现在都二十多的版本了。这里表示任何至少为 0.8.5 但低于 0.9.0 的版本. 紧接着我们需要构建一下代码,用来同步版本库。在DOC命令行输入:

复制代码
cargo build

3. 生成随机数

这里我们需要用到一个库,他就是rand::Rng,这里我们可以使用这个库生成随机数字,使用如下:

css 复制代码
let secret_number = rand::thread_rng().gen_range(1..100);

其中上面的.gen_range()是限制我们的取值范围,1..100是说我们的随机数字就在1~100这个取值范围。

4.将猜测数字与秘密数字进行比较

在这里比较就相对来说容易理解了,如下所示:

ini 复制代码
match guess.cmp(&secret_number){
            Ordering::Less => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => println!("You win!");
}

上面的guess是我们输入的数字,再经过格式转换等操作,然后和我们自己生成的秘密数字secret_number作比较。大括号里面的内容就相当于js中的大于小于和等于了,这一点很好理解,主要说一下Ordering,这个是什么东东,他从哪里来?

Ordering是我们另外一个库use std::cmp::Ordering,这里我们直接将这一行放到文件第一行引入这个库。Ordering::Less这是小于,Ordering::Greater这是大于,Ordering::Equal这个是等于。这里我们注意要将输入的变量放在.cmp之前而不是放在后面的()里面。

5. 使用循环允许多次猜测

这里使用循环就比较简单了,就是使用一个loop将重复使用的代码包起来,如下:

rust 复制代码
loop {
    match guess.cmp(&secret_number){
            Ordering::Less => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => println!("You win!");
    }
}

这里我们发现一个问题,怎么可以一直比较一直循环,如何跳出循环呢,那我们看下面。

6.处理比较两个数字的可能返回值

没错,这里跳出循环同样使用break,Ordering::Less =>这里的箭头,有点像js中的箭头函数,可以放一句话也可以放一个方法。所以代码如下。

ini 复制代码
match guess.cmp(&secret_number){
            Ordering::Less => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => {
                println!("You win!");
                break;
            };
}

也就是说当输入的数字和生成的神秘数字一样了,就提示你胜出了。然后跳出循环。

7.处理无效输入

当然了,假如有人乱输入,比如输入一大堆字符串不输入数字我们怎么办,就需要处理用户输入的数据了,代码如下:

scss 复制代码
let guess: u32 = match guess.trim().parse(){
            Ok(num)=>num,
            Err(_)=>continue,
        };

u32是指的guess类型,用来限定类型相当于TypeScript 的类型限定,这里是说类型为无符号 32 位数字。并且加了个判断,判断将用户输入的内容处理的程序是否出错guess.trim().parse(),这里处理的内容就是先将两边的空格去除,然后再按照u32的格式化,出错的话就跳出这一次循环Err(_)=>continue,继续重新输入。

最后贴上最终的代码,供大家测试把玩。

rust 复制代码
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);
   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(){
           Ok(num)=>num,
           Err(_)=>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;
           }
       }
   }
}

感谢大家观看,我们下次见

相关推荐
猎豹奕叔1 小时前
JD到家商品系统架构设计演进
后端
阑梦清川1 小时前
深入理解动静态库和ELF文件格式
后端
猎豹奕叔1 小时前
面试官:类中两个方法加同步锁,多线程能同时访问吗?
后端
马里奥Mario1 小时前
电商系统商品三四级页接口性能优化记录存档
后端
华农第一蒟蒻1 小时前
谈谈跨域问题
java·后端·nginx·安全·okhttp·c5全栈
绝无仅有2 小时前
面试复盘:哔哩哔哩、蔚来、字节跳动、小红书面试与总结
后端·面试·github
绝无仅有2 小时前
面试经历分享:从特斯拉到联影医疗的历程
后端·面试·github
IT_陈寒2 小时前
JavaScript性能优化:这7个V8引擎技巧让我的应用速度提升了50%
前端·人工智能·后端
Tony Bai8 小时前
【Go开发者的数据库设计之道】07 诊断篇:SQL 性能诊断与问题排查
开发语言·数据库·后端·sql·golang
花花鱼9 小时前
spring boot项目使用tomcat发布,也可以使用Undertow(理论)
spring boot·后端·tomcat