1. 条件结构
Rust 中主要的条件结构为 if
表达式。
1.1 if
表达式
if
表达式的基本语法格式如下:
if <condition1> {
...
} else if <condition2> {
...
} else if <conditionn> {
...
} else {
...
}
其中,else if
和 else
分支都是可选的。表达式中的条件 conditionX
必须是 bool
类型的。
- 由于是表达式,因此可以将
if
表达式的值赋值给变量。 - 由于 Rust 是静态编译语言,要求在编译时就确定所有变量的类型,因此
if
表达式的每个分支可能的返回值都必须相同。
let condition = true;
let branch = if condition {
1
} else {
2
}
2. 循环结构
Rust 中提供的循环结构有 loop
、while
和 for
。Rust 提供 break
表达式用于退出循环,并可选地返回一个返回值。
2.1 loop
loop
结构表示一直执行循环体,直到遇到 break
表达式。
let mut counter = 0;
let result = loop {
counter = 1;
if counter == 10 {
break counter * 2;
}
};
println!("The result is {}", result);
2.2 while
while
结构中,while
关键字后接一个条件表达式用于判断循环是否继续,从而实现条件循环。当然,while
结构可以通过组合 loop
、if
、else
和 break
来实现。
let mut number = 3;
while number != 0 {
println!("{}", number);
number = number - 1;
}
println!("LIFTOFF!!!");
2.3 for
for
结构可以用来遍历集合中的元素和范围空间。虽然可以通过 while
和索引值判断来实现 for
模式,但这个过程很容易出错,也使得程序更慢,因为编译器增加了运行时代码来对每次循环的每个元素进行条件检查。
let a = [10, 20, 30, 40, 50];
// 遍历元素集合
for element in a.iter() {
println!("The value is: {}", element);
}
// 遍历范围区间
// 使用了标准库提供的 Range 类型
for number in (1..4).rev() { // rev 方法用于反转 range
println!("The value is: {}", number);
}
【注】 for
循环的安全性和简洁性使得它成为 Rust 中使用最多的循环结构。
3. 匹配结构
Rust 有一个叫做 match
的极为强大的控制流运算符,它允许我们将一个值与一系列的模式相比较,并根据相匹配的模式执行相应代码。模式可由字面值、变量、通配符和许多其他内容构成。一个 match
匹配示例如下:
enum Coin {
Penny,
Nickel,
Dime,
Quarter,
}
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter => 25,
}
}
match
的一个分支有两个部分:一个模式和一些代码,二者使用=>
分隔。每个分支之间使用,
分隔。- 当
match
表达式执行时,它将结果值按顺序与每一个分支的模式相比较。如果模式匹配了这个值,这个模式相关联的代码将被执行。如果模式并不匹配这个值,将继续执行下一个分支。 match
分支可以绑定匹配模式的部分值,即从枚举成员中提取值。
enum UsState {
Alabama,
Alaska,
// --snip--
}
enum Coin {
Penny,
Nickel,
Dime,
Quarter(UsState),
}
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter(state) => {
println!("State quarter from {:?}!", state);
25
},
}
}
match
必须覆盖所有可能的模式匹配分支,即所谓「穷尽性检查」。不过可以使用_
通配符来实现列举其余未列举出的分支。由于_
通配符会匹配所有的值,所以需要将其放在最后一个分支。
let some_u8_value = 0u8;
match some_u8_value {
1 => println!("one"),
3 => println!("three"),
5 => println!("five"),
7 => println!("seven"),
_ => (),
}
if let
简单控制流 可以看到,match
对于处理只有很少甚至一个分支的情况就比较啰嗦了。另一个简单的控制流if let
语法让我们以一种不那么冗长的方式结合if
和let
,来处理只匹配一个模式的值而忽略其他模式的情况。
- 匹配一个模式举例:
// match 实现
let some_u8_value = Some(0u8);
match some_u8_value {
Some(3) => println!("three"),
_ => (),
}
// if let 实现单模式分支匹配
if let Some(3) = some_u8_value {
println!("three");
}
// if let 实现 match 匹配
if let Some(3) = some_u8_value {
println!("three");
} else {
()
}
if let
获取通过等号分隔的一个模式和一个表达式,它的工作方式与 match 相同。if let
可以使代码更简洁,但会丢失match
强制要求的穷尽性检查。