# 2 ## 输入数字代码 ![image-20221227143849645](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20221227143849645.png) ``` use std::io; ``` 引入io标准库。 ``` let mut guess = String::new(); ``` let 用于创建变量,但是rust默认情况下,变量的值是不可改变的。为了使值可以变化,需在变量名前添加mut; ``` let mut guess = String::new(); ``` 行创建了一个可变变量,该变量当前绑定到一个新的空实例`String` ``` io::stdin() .read_line(&mut guess) ``` 使用此io函数,来允许用户进行输入。若没在开头导入use std::io,也可以使用std::io::stdin来完成此操作。 ![image-20221227144811136](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20221227144811136.png) &表示此参数是一个引用,它为您提供了一种方法,让您的代码的多个部分访问一个数据,而无需将该数据多次复制到内存中。引用和变量一样默认也是不可变的。因此需要使用&mut guess使其可变,而不是使用&guess。 ``` .expect("Failed to read line"); ``` read_line将用户输入的任何内容放入我们传递给它的字符串中,但它也会返回一个Result值。Result是一个enumeration,通常称为enum,它是一种可以处于多种可能状态之一的类型。我们称每个可能的状态为变体。 Result的变体是Ok和Err。Okvariant表示操作成功,里面Ok是成功生成的值。Err变体表示操作失败,并Err包含有关操作失败的方式或原因的信息。 如果您不调用expect,程序将编译,但您会收到警告: ![image-20221227150204236](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20221227150204236.png) ### 占位符 ``` println!("You guessed: {guess}"); ``` {}为占位符,打印变量值时,变量名可以放在大括号内。打印表达式的计算结果时,将空大括号放在格式字符串中,然后在格式字符串后面加上逗号分隔的表达式列表。 ``` #![allow(unused)] fn main() { let x = 5; let y = 10; println!("x = {x} and y + 2 = {}", y + 2); } // res: x = 5 and y = 12 ``` ## 生成随机数 ### rand crate crate是Rust源代码文件的集合,rand crate 是一个库crate,其中包含旨在用于其他程序且不能单独执行的代码。 使用carte前,需要修改Cargo.toml为文件来添加rand crate依赖。 ![image-20221227152350189](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20221227152350189.png) 说明符0.8.5实际上是 的简写^0.8.5,表示任何至少为 0.8.5 但低于 0.9.0 的版本。 ![image-20221227155009707](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20221227155009707.png) 当我们包含一个外部依赖项时,Cargo 会从registry中获取依赖项所需的所有内容的最新版本,这是来自Crates.io的数据副本。Crates.io 是 Rust 生态系统中的人们发布他们的开源 Rust 项目供其他人使用的地方。 Cargo 知道它可以重用它已经为那些下载和编译的东西,所以第二次build无操作。 #### cargo.lock Cargo 有一种机制可以确保您或任何其他人每次构建您的代码时都可以重建相同的工件:Cargo 将仅使用您指定的依赖项版本。具体实现是通过Cargo.lock。由于*Cargo.lock*文件,您的项目将保持在 0.8.5,直到您明确升级。 因为*Cargo.lock*文件对于可重现的构建很重要,所以它通常与项目中的其余代码一起签入源代码管理。 ![image-20221227155552276](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20221227155552276.png) ```rust cargo update ``` 它将忽略Cargo.lock文件并在Cargo.toml中找出符合你的规范的所有最新版本。然后 Cargo 会将这些版本写入Cargo.lock文件。 ### 生成随机数 ![image-20221227161031139](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20221227161031139.png) ``` use rand::Rng ``` Rng特征定义了随机数生成器实现的方法。 ``` rand::thread_rng ``` 为我们提供我们将要使用的特定随机数生成器的函数:一个在当前执行线程本地并由操作系统播种的随机数生成器。 ``` gen_range ``` 该 gen_range方法将范围表达式作为参数并生成范围内的随机数。我们在这里使用的范围表达式的形式start..=end是包含下限和上限。 ``` cargo doc --open ``` ![image-20221227161704399](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20221227161704399.png) 可以查看当前项目所有的依赖项文档。 ### 比较大小 下面代码存在String和integer不匹配的类型错误,仅是为了方便记录新增内容。 ![image-20221227162225237](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20221227162225237.png) ``` std::cmp::Ordering ``` 该Ordering类型是另一个枚举,具有变体Less、Greater和Equal。当您比较两个值时,这些是可能的三种结果。 match类似switch,会根据 cmp``guess``secret_number 返回不同的结果。 #### 类型转换 ![image-20221227170812732](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20221227170812732.png) ``` let guess: u32 = guess.trim().parse().expect("Please type a number!"); ``` Rust允许我们guess用一个新值来遮盖以前的值,当要将值从一种类型转换为另一种类型时,通常会用到此。 数字类型有u32和i64,故字符串转换为数字时,需要显式说明具体数字类型。用:来指定。 #### 循环 ![image-20221227172724375](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20221227172724375.png) 循环成功,新增break ![image-20221227172955774](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20221227172955774.png) #### 处理用户输入非数字退出问题 ![image-20221227173709707](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20221227173709707.png) 我们从一个expect调用切换到一个match表达式,从错误崩溃转移到处理错误。它parse返回一个Result 类型并且Result是一个具有变体Ok和的枚举Err