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;
           }
       }
   }
}

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

相关推荐
舒一笑19 分钟前
如何优雅统计知识库文件个数与子集下不同文件夹文件个数
后端·mysql·程序员
IT果果日记20 分钟前
flink+dolphinscheduler+dinky打造自动化数仓平台
大数据·后端·flink
Java技术小馆31 分钟前
InheritableThreadLoca90%开发者踩过的坑
后端·面试·github
寒士obj41 分钟前
Spring容器Bean的创建流程
java·后端·spring
数字人直播2 小时前
视频号数字人直播带货,青否数字人提供全套解决方案!
前端·javascript·后端
shark_chili2 小时前
提升Java开发效率的秘密武器:Jadx反编译工具详解
后端
武子康2 小时前
大数据-75 Kafka 高水位线 HW 与日志末端 LEO 全面解析:副本同步与消费一致性核心
大数据·后端·kafka
YANGZHAO2 小时前
Docker零基础入门:一文搞定容器化核心技能
后端·docker
字节跳跃者2 小时前
SpringBoot + MinIO + kkFile 实现文件预览,这样操作更安全!
java·后端·程序员
我是哪吒2 小时前
分布式微服务系统架构第167集:从零到能跑kafka-redis实战
后端·面试·github