猜数字的游戏
根据官方教程,照写一个程序,来体验一下rust的程序开发过程。
需求游戏很简单, 就是一次次输入比对预先生成的随机数。
- 随机产生一个数字
- 让用户输入,并比对大小,给出提示
- 直到猜中数字。
- cargo 引入随机数包
- 基本的rust语句使用,基本的rust的函数使用。
- 了解工程从搭建到编写到编译生成的完成过程。
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可以下载第三方库。
同时cargo 也可以用来建立自己的rust项目, 包括可行性程序以及库。
可以通过
cargo new project_name -bin 创建一个rust程序
cargo new project_name --lib 创建一个库
cargo 库再rust 第三方库叫crates, 可以通过https://crates.io/上找到。
本例子中使用rand, 可以找到该库文件。
工程建立一些代码的编写, 本章节不做细节描述。 概要说明一下
建立工程 $ 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!