Rust 学习-4-猜数字游戏

猜数字的游戏

根据官方教程,照写一个程序,来体验一下rust的程序开发过程。

需求

游戏很简单, 就是一次次输入比对预先生成的随机数。

  1. 随机产生一个数字
  2. 让用户输入,并比对大小,给出提示
  3. 直到猜中数字。

涉及到的知识点

  1. cargo 引入随机数包
  2. 基本的rust语句使用,基本的rust的函数使用。
  3. 了解工程从搭建到编写到编译生成的完成过程。

开始

Cargo是rust的包管理工具, 对于本需求需要rand的方法, 但是该方法再rust中并不存在, 所以通过Cargo引入了第三方包的方式进行使用。

Cargo 说明

Cargo 不仅仅是一个包管理器,同时还是Rust项目的管理工具。

可以通过cargo的帮助信息查看命令以及功能说明. cargo -h

 Rust's package manager
 
 Usage: cargo [+toolchain] [OPTIONS] [COMMAND]
        cargo [+toolchain] [OPTIONS] -Zscript <MANIFEST_RS> [ARGS]...
 
 Options:
   -V, --version             Print version info and exit
       --list                List installed commands
       --explain <CODE>      Provide a detailed explanation of a rustc error message
   -v, --verbose...          Use verbose output (-vv very verbose/build.rs output)
   -q, --quiet               Do not print cargo log messages
       --color <WHEN>        Coloring: auto, always, never
   -C <DIRECTORY>            Change to DIRECTORY before doing anything (nightly-only)
       --frozen              Require Cargo.lock and cache are up to date
       --locked              Require Cargo.lock is up to date
       --offline             Run without accessing the network
       --config <KEY=VALUE>  Override a configuration value
   -Z <FLAG>                 Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details
   -h, --help                Print help
 
 Commands:
     build, b    Compile the current package
     check, c    Analyze the current package and report errors, but don't build object files
     clean       Remove the target directory
     doc, d      Build this package's and its dependencies' documentation
     new         Create a new cargo package
     init        Create a new cargo package in an existing directory
     add         Add dependencies to a manifest file
     remove      Remove dependencies from a manifest file
     run, r      Run a binary or example of the local package
     test, t     Run the tests
     bench       Run the benchmarks
     update      Update dependencies listed in Cargo.lock
     search      Search registry for crates
     publish     Package and upload this package to the registry
     install     Install a Rust binary. Default location is $HOME/.cargo/bin
     uninstall   Uninstall a Rust binary
     ...         See all commands with --list
 
 See 'cargo help <command>' for more information on a specific command.

可以通过 cargo --list 查看所提供的命令

 Installed Commands:
     add                  Add dependencies to a Cargo.toml manifest file
     b                    alias: build
     bench                Execute all benchmarks of a local package
     build                Compile a local package and all of its dependencies
     c                    alias: check
     check                Check a local package and all of its dependencies for errors
     clean                Remove artifacts that cargo has generated in the past
     clippy               Checks a package to catch common mistakes and improve your Rust code.
     config               Inspect configuration values
     d                    alias: doc
     doc                  Build a package's documentation
     fetch                Fetch dependencies of a package from the network
     fix                  Automatically fix lint warnings reported by rustc
     fmt                  Formats all bin and lib files of the current crate using rustfmt.
     generate-lockfile    Generate the lockfile for a package
     git-checkout         This command has been removed
     help                 Displays help for a cargo subcommand
     init                 Create a new cargo package in an existing directory
     install              Install a Rust binary. Default location is $HOME/.cargo/bin
     locate-project       Print a JSON representation of a Cargo.toml file's location
     login                Log in to a registry.
     logout               Remove an API token from the registry locally
     metadata             Output the resolved dependencies of a package, the concrete used versions including overrides, in machine-readable format
     miri
     new                  Create a new cargo package at <path>
     owner                Manage the owners of a crate on the registry
     package              Assemble the local package into a distributable tarball
     pkgid                Print a fully qualified package specification
     publish              Upload a package to the registry
     r                    alias: run
     read-manifest        Print a JSON representation of a Cargo.toml manifest.
     remove               Remove dependencies from a Cargo.toml manifest file
     report               Generate and display various kinds of reports
     rm                   alias: remove
     run                  Run a binary or example of the local package
     rustc                Compile a package, and pass extra options to the compiler
     rustdoc              Build a package's documentation, using specified custom flags.
     search               Search packages in crates.io
     t                    alias: test
     test                 Execute all unit and integration tests and build examples of a local package
     tree                 Display a tree visualization of a dependency graph
     uninstall            Remove a Rust binary
     update               Update dependencies as recorded in the local lock file
     vendor               Vendor all dependencies for a project locally
     verify-project       Check correctness of crate manifest
     version              Show version information
     yank                 Remove a pushed crate from the index

Cargo中,每个命令均可通过 -help 的方式来查看具体命令的用法, 例如: cargo run -help

较为常用的如下:

  • cargo build :编译当前项目
  • cargo check:分析当前项目并报告,但不产出文件
  • cargo run:执行src/main.rs
  • Cargo clear:移除当前项目的target目录
  • Cargo update:更新当前项目中的依赖
  • cargo new: 创建一个新工程。

cargo 创建rust项目

作为包管理工具,cargo可以*载下**第三方库。

同时cargo 也可以用来建立自己的rust项目, 包括可行性程序以及库。

可以通过

cargo new project_name -bin 创建一个rust程序

cargo new project_name --lib 创建一个库

cargo 库

再rust 第三方库叫crates, 可以通过https://crates.io/上找到。

本例子中使用rand, 可以找到该库文件。

Rust学习-4-猜数字游戏

开始建立工程

工程建立一些代码的编写, 本章节不做细节描述。 概要说明一下

建立工程

 $ cargo new guess-game-app
 Created binary (application) `guess-game-app` package
 $ cd guess-game-app

加入依赖

修改toml文件,加入rand依赖

 [package]
 name = "guess-game-app"
 version = "0.1.0"
 edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
 rand="0.8.5"

编译

编译 cargo build cargo check

引入包后,习惯的执行编译, 会导入对应的包文件。

     Updating crates.io index
   Downloaded rand_chacha v0.3.1
   Downloaded cfg-if v1.0.0
   Downloaded ppv-lite86 v0.2.17
   Downloaded rand_core v0.6.4
   Downloaded getrandom v0.2.11
   Downloaded rand v0.8.5
   Downloaded libc v0.2.150
   Downloaded 7 crates (910.0 KB) in 4.23s
    Compiling libc v0.2.150
    Compiling cfg-if v1.0.0
    Compiling ppv-lite86 v0.2.17
    Compiling getrandom v0.2.11
    Compiling rand_core v0.6.4
    Compiling rand_chacha v0.3.1
    Compiling rand v0.8.5
    Compiling guess-game-app v0.1.0 (/Users/zhuchunlei/work/08_rust/guess-game-app)
     Finished dev [unoptimized + debuginfo] target(s) in 12.11s

源码

修改源文件,src/main.rs(代码来源教程中,目前为止只是照着敲, 具体含义再逐渐学习理解)

 use rand::Rng;
 use std::cmp::Ordering;
 use std::io;
 
 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;
             }
         }
     }
 }

编译执行

 cargo run                                       [15:29:54]
    Compiling guess-game-app v0.1.0 (/Users/zhuchunlei/work/08_rust/guess-game-app)
     Finished dev [unoptimized + debuginfo] target(s) in 0.65s
      Running `target/debug/guess-game-app`
 Guess the number!
 Please input your guess.
 50
 You guessed: 50
 Too big!
 Please input your guess.
 40
 You guessed: 40
 Too big!
 Please input your guess.
 20
 You guessed: 20
 Too small!
 Please input your guess.
 30
 You guessed: 30
 Too small!
 Please input your guess.
 35
 You guessed: 35
 Too big!
 Please input your guess.
 33
 You guessed: 33
 You win!