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()

  • ::用于访问关联函数

  • stdin()是一个函数,这个函数用于获取标准输入流(standard input),返回Stdin类型的实例,它会被用作句柄(handle) 来处理终端中的标准输入。

  • .read_line()Stdin 类型提供的方法,用于从标准输入中读取一行内容给放到字符串中,传递给可变的字符串类型变量read_line()还有一个返回值,类型是Result,一种枚举类型,它有两个值:OkErr。如果read_line()能成功读取,那这个枚举类型就会返回Ok和读取到的内容;如果不能读取,就会返回Err和读取失败的原因。

  • &mut guess指的是把.read_line()所读取到的内容传入到这个可变变量guess里。这里的&是取地址符,表示这个参数是一个引用,通过引用就可以在代码的不同地方访问同一块数据(内存地址)。mut指传递给的是可变变量。

  • 在读取时可能发生错误,这里就需要调用.expect() ,它是 Result 类型(与read_line()的返回值同类型)的一个方法。如果读取失败,按上文所述,read_line()就会返回Err.expect()接收到后会直接触发 panic! 终止当前程序并打印 expect 中的错误信息。反之,read_line()就会返回Ok,.expect()接收到后就会把附加的值返回给用户。 PS:也可以不写.expect(),但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);
}

效果: