Skip to main content

Gatech CS3210 学习笔记 - lab0 part1

· 6 min read

写这篇的主要原因是 rust 的控制语句语法比较复杂,相对于 c 增加了一点点新特性[,我在看的时候脑子就已经开始思考用在哪里哪里很优美之类的事情了]。 rustling 的机制很有意思,它会根据配置文件对代码逐个编译,只验证代码是否能通过编译。所以在实操的时候有非常大的自由,rustling 也鼓励多尝试不同的解法,可惜的是没有老师 review 我的作业。 这一篇记录第四章到第八章的内容。

学会了什么

  • 编译器会对未使用的变量抛出 warning,但以下划线开头的变量不会
  • rust 对变量作用域和二次声明提出了shadow的概念,简单来说就是let语句会覆盖本代码块和外层代码块的同名变量,对覆盖前后的变量类型、可变性没有要求,在本代码块中被覆盖的变量无法恢复,退出本代码块后被覆盖的外层变量会恢复(就是个作用域问题)。在造成shadowlet语句中可以使用被覆盖变量的值。
  • rust 不提倡对变量先声明而不初始化,编译器会对可能的未初始化而使用的情况抛出 error
  • rust 不进行隐式类型转换,显式类型转换的关键字为as
  • rust 的数值字面量可以用类型名修饰,比如1u8就是八位无符号整数1。
  • 在声明变量时可以使用:显式声明类型,但是文档对编译器的自动类型推断非常自信
  • std::convert::From std::convert::TryFrom可以实现自定义类型的类型转换函数,后者支持异常处理。fmt::Display如上一篇中猜测的会自动实现to_string函数
  • rust 将代码块作为表达式处理,而且代码块的反大括号后面必须有分号。代码块的返回值取决于最后一行代码,若最后一行没有分号则会返回最后一行的值,若有则返回()。所以代码块是可以用来赋值的,值得注意的是,下面的控制语句中的代码块同样适用这个规则

重点是控制语句

rust 很自然地删掉了 c 语言中的switch语法,提供了更复杂但也更好用的match语法。除此之外还有常见的if-else while for-in等。

  • if-else大概是最好懂的语法了,除了布尔表达式不需要圆括号、代码块必须有大括号之外没有什么特别之处
  • while的额外特性也不多,可以使用例如'label: while true { break 'label; }的语法退出特定层级的循环。loop就是while true的语法糖
  • for-in虽然和 c 有差别但和其他现代语言没有太大差别,举个例子for n in 1..101 {},但是令我比较迷惑的是这个用例for n in 1..=100 {}会将原本的左闭右开区间变成左闭右闭区间,两个例子都是循环到100,不太明白这是糖还是有别的目的。for-in还支持迭代器,但是现在看不太懂等后面章节吧
  • match的语法看得我头大,所以我决定直接上代码

!match用例

let number = 13;

match number {
// Match a single value
1 => println!("One!"),
// Match several values
2 | 3 | 5 | 7 | 11 => println!("This is a prime"),
// Match an inclusive range
// Bind to `n` for the sequence of 13 ..= 19
n @ 13..=19 => println!("A teen of age {}", n),
// Handle the rest of cases
_ => println!("Ain't special"),
}

let triple = (0, -2, 3);

// A match block can destructure items in a variety of ways
match triple {
// A match guard can be added to filter the arm
(0, y, z) => if y == z => println!("These are twins"),
// Destructure the second and third elements
(0, y, z) => println!("First is `0`, `y` is {:?}, and `z` is {:?}", y, z),
(1, ..) => println!("First is `1` and the rest doesn't matter"),
// `..` can be the used ignore the rest of the tuple
_ => println!("It doesn't matter what they are"),
// `_` means don't bind the value to a variable
}
  • if let以我的理解就是一个特殊的if语句,布尔表达式是一个let语句,该语句会像match一样解构类型,如果解构成功则执行代码块,失败则跳转到else
  • while let同理,在布尔表达式中尝试解构但代码块从if let的选择控制变成了循环控制