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

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

相关推荐
老华带你飞20 小时前
二手商城|基于springboot 二手商城系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·spring
Tadas-Gao20 小时前
GraphQL:下一代API架构的设计哲学与实践创新
java·分布式·后端·微服务·架构·graphql
老华带你飞20 小时前
酒店预约|基于springboot 酒店预约系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·spring
dob20 小时前
为什么你的if-else越写越乱?聊聊状态机
后端
古城小栈20 小时前
Spring Boot + 边缘 GenAI:智能座舱应用开发实战
java·spring boot·后端
开心就好202521 小时前
使用 Ipa Guard 应对 App Store 4.3 风险的一些实践
后端
想用offer打牌21 小时前
一站式了解数据库三大范式(库表设计基础)
数据库·后端·面试
2501_9419820521 小时前
Go 进阶:发送文件/图片消息的流程与实现
开发语言·后端·golang
2301_8002561121 小时前
第十一章中的函数解读(1)
后端·asp.net