rust学习-20230629

  • cargo build 编译rust
  • cargo check 快速检查 rust 代码,因为不需要执行编译所以速度很快。
  • cargo run 会检查代码是否有修改,如果没有修改的话直接运行之前生成的二进制文件,如果有修改才重新执行构建后运行。
  • cargo build构建执行完毕后二进制文件存放在target/debug目录下
  • cargo build --release构建执行完毕后二进制文件存放在target/release目录下,这种模式会以更长的编译时间为代价来优化代码,从而使代码拥有更好的运行时性能。这也是存在两种不同的构建模式的原因。一种模式用于开发,它允许你快速地反复执行构建操作。而另一种模式则用于构建交付给用户的最终程序,这种构建场景不会经常发生,但却需要生成的代码拥有尽可能高效的运行时表现。值得指出的是,假如你想要对代码的运行效率进行基准测试,那么请确保你会通过cargo run --release命令进行构建,并使用target/release目录下的可执行程序完成基准测试。
定义变量使用let关键字,默认变量赋值后不可变,可使用mut关键字声明是可变变量 let foo = 5; // foo不可变 let mut foo = 5; // foo 可变

String::new中的::语法表明new是String类型的一个关联函数(associated function)。
这个new函数会创建一个新的空白字符串。
语句let mut guess = String::new();会创建出一个可变的变量,并在它身上绑定一个新的空白字符串。

如果没有在程序的开始处添加use std::io;行,那么就需要将这个函数调用修改为std::io::stdin。stdin函数会返回类型std::io::Stdin的实例

.read_line(&mut guess),调用了标准输入句柄的read_line方法来获得用户输入。另外,read_line还在调用的过程中使用了一个参数:&mut guess。
参数前面的&意味着当前的参数是一个引用。你的代码可以通过引用在不同的地方访问同一份数据。
引用与变量一样,默认情况下也是不可变的。因此,你需要使用&mut guess而不是&guess来声明一个可变引用。
read_line会将用户输入的内容存储到我们传入的字符串中,但与此同时,它还会返回一个io::Result值。Result是一个枚举类型。枚举类型由一系列固定的值组合而成,这些值被称作枚举的变体。它拥有Ok和Err两个变体。其中的Ok变体表明当前的操作执行成功,并附带代码产生的结果值。相应地,Err变体则表明当前的操作执行失败,并附带引发失败的具体原因。

库包引入

Rust中的包(crate)代表了一系列源代码文件的集合。 package也可以理解为包,但是它是多个包的集合 package理解为包,crate为单元包

Cargo生成的Cargo.toml的[dependencies]区域下方添加依赖
[dependencies]
rand = “0.8.5”

库升级

Cargo.lock保证了代码第一次构建的时候,会优先检索该文件,跳过计算版本号的操作,直接使用文件内指定的版本。 如果需要升级则需要执行cargo update,这时候Cargo.lock也会更新为现在最新版本的库。 其中 x 被称为主版本major, y 被称为小版本 minor ,而 z 被称为补丁 patch 如上面写入的依赖版本,基于语义化版本的规则,Cargo在自动升级时只会寻找大于0.8.0并小于0.9.0的最新版本。假如rand包发布了两个新版本:0.8.5和0.9.0,那么当你运行cargo update时只会升级到0.8.5,需要跨小版本的话,需要修改toml文件内的版本号。 [dependencies] rand = "^0.8.5" ^可以指定一个版本号范围,然后会使用该范围内的最大版本号来引用对应的包。 只要新的版本号没有修改最左边的非零数字,那该版本号就在允许的版本号范围中。例如 "^0.8.5" 最左边的非零数字是8,因此,只要新的版本号是 "0.8.z" 就可以落在范围内,而0.9.0 显然就没有落在范围内,因此通过 "^0.8.5" 引入的依赖包是无法被升级到 0.9.0 版本的。

范围取值

rand::thread_rng().gen_range(1, 101); rust的range区间是用..而不是,分割上标和下标的

已引入的依赖如何创建本地文档

cargo doc --open

匹配模式

我理解有点像switch,match表达式由数个分支(arm)组成,每个分支都包含一个用于匹配的模式(pattern),以及匹配成功后要执行的相应的代码。

对比匹配,强制类型

Rust有一个静态强类型系统,同时,它还拥有自动进行类型推导的能力。当我们编写let guess = String::new()时,虽然我们没有做出任何显式的声明,但Rust会自动将变量guess的类型推导为String。另一方面,secret_number是一个数值类型。有许多数值类型可以包含从1到100之间的整数,比如i32(32位整数)、u32(32位无符号整数)、i64(64位整数)等。除非我们在代码中增加更多用于推导类型的信息,否则Rust会默认将secret_number视作i32类型。总而言之,编译器指出的错误就是:Rust无法将字符串类型(String类型)和数值类型直接进行对比。 Rust允许使用同名的新变量guess来隐藏(shadow)旧变量的值。这一特性通常被用在需要转换值类型的场景中,它在本例中允许我们重用guess这个变量名,而无须强行创造出guess_str之类的不同的名字

循环

loop关键字会创建一个无限循环。

异常处理

match比expect更为常用,parse()会返回一个result,里面包含了Ok和Err两个变体,通过match去匹配,然后执行后续的动作。