Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

2.1 猜数游戏Pt.1 一次猜测

2.1.0 本篇知识点

在本篇中,你将学到:

  • 变量的声明
  • 相关的函数
  • 枚举类型
  • println!() 的进阶使用

2.1.1 游戏目标

  • 生成一个 1 到 100 间的随机数
  • 提示玩家输入一个猜测(本篇会涉及)
  • 猜完之后,程序会提示猜测是太大了还是太小了
  • 如果猜测正确,那么打印一个庆祝信息,程序退出

2.1.2 代码实现

Step 1:打印出游戏名并提示用户输入

fn main() {

}
  • 通过 println!() 这个宏来打印文本:
fn main() {
    println!("Number Guessing Game");

    println!("Guess a number");
}

Step 2:创建变量来存储用户的输入

在提示用户输入后,这个程序会需要一个变量来存储用户输入,这一行的代码应如下:

#![allow(unused)]
fn main() {
let mut guess = String::new();
}
  • let 用于声明一个新变量,默认情况下变量是不可变的。
  • let 后面加上 mut 代表声明的这个变量是可变的。
  • guess 是这个变量的名字。
  • = 用于赋值。
  • String::new() 是用来创建一个新的、空的字符串的静态方法。String 是 Rust 标准库提供的 UTF-8 动态字符串类型。:: 表明 new()String 类型的关联函数,关联函数是针对类型本身实现的,而不是针对某个具体字符串实例实现的,类似于 C# 或 Java 中的静态方法。调用 String::new() 会返回一个新的 String 实例,且其中没有任何内容,也就是空字符串。

Rust 的很多类型都有 new() 函数,new() 是创建类型实例的常见名称。

Step 3:获取用户的输入

接下来我们需要读取用户的输入,这部分代码如下:

#![allow(unused)]
fn main() {
io::stdin().read_line(&mut guess).expect("Could not read the line");
}
  • io模块名。这个模块中有我们所需的 stdin() 函数。
  • 这里的 :: 用于通过模块路径访问其中的项(如 std::io::stdin)。
  • stdin() 是一个函数,这个函数用于获取标准输入流,并返回 Stdin 类型的实例。它会被用作句柄(handle) 来处理终端中的标准输入。
  • .read_line()Stdin 类型提供的方法。它从标准输入中读取一行内容放到字符串中,并传递给一个可变的字符串变量read_line() 还会返回一个 Result,这是一种有两个变体的枚举:OkErr。如果 read_line() 成功,它会返回 Ok 以及读取到的字节数;如果失败,它会返回 Err 以及失败原因。
  • &mut guess 指的是把 .read_line() 所读取到的内容传入到这个可变变量 guess 里。这里的 & 表示取引用,通过引用就可以在代码的不同地方访问同一块数据(内存地址)。mut 表示被引用的变量是可变的。
  • 在读取时可能发生错误,这里就需要调用 .expect(),它是 read_line() 返回的 Result 类型上的一个方法。如果读取失败,read_line() 就会返回 Err.expect() 会立即触发 panic!,终止当前程序,并打印传给 expect 的错误信息。如果读取成功,read_line() 就会返回 Ok.expect() 会把附加的值返回出来。 展示 read_line 成功(Ok)与失败(Err)经 expect() 处理的流程图 PS:也可以省略 .expect(),但 cargo build 时会发出警告。

如果你正在 IDE 里写到这里,你会发现 io 这处被标红了。这是因为这个程序还没有声明依赖这个模块。只需要在程序开头添加导入即可:

#![allow(unused)]
fn main() {
use std::io;
}
  • use 是导入的关键字。
  • std::io 是指标准库(std)下的 io 这个模块。

也可以直接在调用了 io 模块的这一行前加上库名,这样就不用在程序开头添加导入:

#![allow(unused)]
fn main() {
std::io::stdin().read_line(&mut guess).expect("Could not read the line");
}

事实上,在默认情况下 Rust 会把一个叫 prelude 的模块的内容导入到每个程序的作用域(这个概念之后会讲)中,有人把它叫做预导入模块。如果你要使用的类型不在 prelude 里,就需要显式导入。

Step 4:打印用户的输入

最后,打印出用户输入:

#![allow(unused)]
fn main() {
println!("The number you guessed is:{}", guess);
}
  • "The number you guessed is:{}" 中的 {} 是占位符,它的值在输出时会被替换为后面变量的值,这里就是 guess

2.1.3 代码效果

这是完整的代码:

use std::io;

fn main() {
    println!("Number Guessing Game");

    println!("Guess a number");

    let mut guess = String::new();

    io::stdin().read_line(&mut guess).expect("Could not read the line");

    println!("The number you guessed is:{}", guess);
}

效果:

Number Guessing Game
Guess a number
10
The number you guessed is:10