Skip to content
Published at:

编写猜猜看游戏

介绍常用概念:let, match, 方法, 关联函数, 外部crate等

游戏:

  1. 新建项目
  2. 处理一次猜测
  3. 生成一个秘密数字
  4. 比较猜测的数字和秘密数字
  5. 使用循环来允许多次猜测

1.新建项目

bash
$ cargo new guessing_game

2.处理一次猜测

rust
use std::io;

fn main() {
    println!("Guess the number!");
    println!("please input your number:");

    let mut guess = String::new();
    io::stdin()
        .read_line(&mut guess)
        .expect("Failed to read line");

    println!("guess = {}", guess);
}

use关键字

rust程序会隐式的导入std::prelude模块:包含一些常用的,必要的模块

变量默认不可变

关联函数(associated function),关联函数是针对类型实现的,有些语言把它成为静态方法(static method)

&表示引用(reference),用来访问数据,无需在内存中拷贝

Result类型是枚举(enumerations),枚举是持有固定集合的值,这些值被称为枚举的成员(variants), Result的成员是OkErr,Ok表示操作成功,内部包含成功时产生的值,Err成员则表示意味着操作失败,并且包括失败的前因后果,

如果Result实例的值是Err,expect会导致程序崩溃,并显示expect参数的信息

如果Result实例的值是Ok,expect会获取Ok中的值并原样返回,

println!占位符

标准库中有很多Result类型,在对应子模块中

3.生成一个秘密数字

crate是一个代码包:

  • 二进制crate:当前项目

  • 库crate:三方库,rand库

toml
[package]
name = "guessing_game"
version = "0.1.0"
authors = ["shibin <15519900807@qq.com>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rand = "0.8.3"

0.8.3事实上是^0.8.3的简写,表示"任何与0.8.3版本公有API相兼容的版本"

语义化版本:Semantic Versioning

bash
$ cargo build
  • cargo会从registry上获取所有包的最新版本信息,从crates.io获取,
  • 下载缺失的依赖,以及依赖的依赖...
  • 编译依赖,使用这些依赖编译项目

Cargo.lock文件:确保构建是可重现的

bash
# 更新依赖:只会更新PATCH版本,不会更新MAJOR.MINOR版本
$ cargo udpate

# 生成当前项目及依赖的文档,并用浏览器打开
$ cargo doc --open
rust
use std::io;

use rand::Rng;

fn main() {
    println!("Guess the number!");
    println!("please input your number:");

    let mut guess = String::new();
    io::stdin()
        .read_line(&mut guess)
        .expect("Failed to read line");

    let num = rand::thread_rng().gen_range(0..=100);
    println!("the secret number = {}", num);

    println!("guess = {}", guess);
}

4.比较猜测的数字和秘密数字

rust
use std::{cmp::Ordering, io};

use rand::Rng;

fn main() {
    println!("Guess the number!");
    println!("please input your number:");

    let mut guess = String::new();
    io::stdin()
        .read_line(&mut guess)
        .expect("Failed to read line");

    let secret_number = rand::thread_rng().gen_range(0..=100);
    println!("the secret number = {}", secret_number);

    let guess: i32 = guess.trim().parse().expect("Failed to parse guess");

    match guess.cmp(&secret_number) {
        Ordering::Less => println!("too small"),
        Ordering::Equal => println!("you win"),
        Ordering::Greater => println!("too big"),
    }
}

std::cmp::Ordering 枚举:

match表达式:

变量shadow:新的变量隐藏以前的变量值.常用在需要转换值类型的场景

函数trim, parse,

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

  • 用循环允许多次猜测
  • 用match处理输入错误
rust
use rand::Rng;
use std::{cmp::Ordering, io};

fn main() {
    println!("Guess the number!");
    println!("please input your number:");
    let secret_number = rand::thread_rng().gen_range(0..=100);
    println!("the secret number = {}", secret_number);

    loop {
        let mut guess = String::new();
        io::stdin()
            .read_line(&mut guess)
            .expect("Failed to read line");

        let guess: i32 = match guess.trim().parse() {
            Ok(number) => number,
            Err(_) => continue,
        };

        match guess.cmp(&secret_number) {
            Ordering::Less => println!("too small"),
            Ordering::Greater => println!("too big"),
            Ordering::Equal => {
                println!("you win");
                break;
            }
        }
    }
}