学习 Rust 时的笔记1
Jun 28, 2022
学习 Rust 时的笔记
Rust语言设计,更像是一个有实战经验的语言设计专家的作品,而非一些学院派的作品。
学习的时候,常用于和go的语法比较,因为我此前3个月,一直在写go和dart语言。
内部结构
fn main(){
struct Foo {x: (u32,u32),y:u32,}
}
与go不同,go的内部匿名结构体,是不支持声明名字的,但rust可以
枚举
#[allow(dead_code)]
enum Color {
// 这三个取值仅由它们的名字(而非类型)来指定。
Red,
Blue,
Green,
// 这些则把 `u32` 元组赋予不同的名字,以色彩模型命名。
RGB(u32, u32, u32),
HSV(u32, u32, u32),
HSL(u32, u32, u32),
CMY(u32, u32, u32),
CMYK(u32, u32, u32, u32),
}
rust 在声明枚举的时候,将枚举值定义为某一个类似于结构体的东西,这个很方便,配合 rust 中的 match,好用。
卫语句
fn main() {
let pair = (2, -2);
// 试一试 ^ 将不同的值赋给 `pair`
println!("Tell me about {:?}", pair);
match pair {
(x, y) if x == y => println!("These are twins"),
// ^ `if` 条件部分是一个卫语句
(x, y) if x + y == 0 => println!("Antimatter, kaboom!"),
(x, _) if x % 2 == 1 => println!("The first one is odd"),
_ => println!("No correlation..."),
}
}
这里可以看到,在 match 中,有点像解构赋值。
绑定
在 match 中,提供了 @ 符号去直接的访问某一个变量,将变量的值,绑定到 @ 符号中
// `age` 函数,返回一个 `u32` 值。
fn age() -> u32 {
15
}
fn main() {
println!("Tell me what type of person you are");
match age() {
0 => println!("I haven't celebrated my first birthday yet"),
// 可以直接匹配(`match`) 1 ..= 12,但那样的话孩子会是几岁?
// 相反,在 1 ..= 12 分支中绑定匹配值到 `n` 。现在年龄就可以读取了。
n @ 1 ..= 12 => println!("I'm a child of age {:?}", n),
n @ 13 ..= 19 => println!("I'm a teen of age {:?}", n),
// 不符合上面的范围。返回结果。
n => println!("I'm an old person of age {:?}", n),
}
}
这个地方的代码,应该是从右往左读
- 将 1~12的值,放到n
- 将13 ~ 19的值,放到n
Match 解构
fn main() {
// 将 `optional` 设为 `Option<i32>` 类型
let mut optional = Some(0);
// 这读作:当 `let` 将 `optional` 解构成 `Some(i)` 时,就
// 执行语句块(`{}`)。否则就 `break`。
while let Some(i) = optional {
if i > 9 {
println!("Greater than 9, quit!");
optional = None;
} else {
println!("`i` is `{:?}`. Try again.", i);
optional = Some(i + 1);
}
// ^ 使用的缩进更少,并且不用显式地处理失败情况。
}
// ^ `if let` 有可选的 `else`/`else if` 分句,
// 而 `while let` 没有。
}
变量i由 match 解构得出,类型为 i32
闭包
rust 中闭包函数和普通函数的声明方式并不相同
fn main() {
// 通过闭包和函数分别实现自增。
// 译注:下面这行是使用函数的实现
fn function(i: i32) -> i32 {
i + 1
}
// 闭包是匿名的,这里我们将它们绑定到引用。
// 类型标注和函数的一样,不过类型标注和使用 `{}` 来围住函数体都是可选的。
// 这些匿名函数(nameless function)被赋值给合适地命名的变量。
let closure_annotated = |i: i32| -> i32 { i + 1 };
let closure_inferred = |i| i + 1;
// 译注:将闭包绑定到引用的说法可能不准。
// 据[语言参考](https://doc.rust-lang.org/beta/reference/types.html#closure-types)
// 闭包表达式产生的类型就是 “闭包类型”,不属于引用类型,而且确实无法对上面两个
// `closure_xxx` 变量解引用。
let i = 1;
// 调用函数和闭包。
println!("function: {}", function(i));
println!("closure_annotated: {}", closure_annotated(i));
println!("closure_inferred: {}", closure_inferred(i));
// 没有参数的闭包,返回一个 `i32` 类型。
// 返回类型是自动推导的。
let one = || 1;
println!("closure returning one: {}", one());
}