控制流
在大多数编程语言中,根据条件是否为 true
执行一些代码以及在条件为 true
时重复执行一些代码的能力是大多数编程语言的构建基石。
If Else
fn main() {
let a = 58;
if a < 0 {
print!("{} is negative", a);
} else if a > 0 {
print!("{} is positive", a);
} else {
print!("{} is zero", a);
}
}
Loop
Rust 提供了 loop
关键字来表示无限循环。与其他类似 C 系语言一样,break
语句可用于在任何时候退出循环,而 continue
语句可用于跳过迭代剩余逻辑并开始新的迭代。
fn main() {
let mut count = 0;
loop {
count += 1;
if count == 7 {
println!("seven");
continue;
}
println!("{}", count);
if count == 10 {
println!("Let's end here!");
break;
}
}
}
Loop 标签
你可以为循环加上一些 'label
标签。break
或 continue
可以通过标签直接控制外层循环。
fn main() {
'outer: loop {
println!("The outer loop begins");
'inner: loop {
println!("The inner loop begins");
break 'outer;
}
println!("Unreachable line here");
}
println!("The outer loop ends");
}
从循环中返回
你可以在 break
后放置返回值,它将被 loop
表达式直接返回。
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("counter: {} result: {}", counter, result);
// counter: 10 result: 20
}
While
fn main() {
let mut n = 1;
while n < 10 {
if n % 2 == 0 {
println!("{}", n);
}
n += 1;
}
}
For
a..b
写法可以在 Rust 中创建区间(range)
。for ... in
结构可用于遍历区间,或者广义上地,可以遍历迭代器 Iterator
。
fn main() {
for n in 1..5 {
print!("{} ", n); // 1 2 3 4
}
}
如果要包含区间的末尾元素,使用 a..=b
写法。
fn main() {
for n in 1..=5 {
print!("{} ", n); // 1 2 3 4 5
}
}
iter
, iter_mut
和 into_iter
分别以不同的方式将集合转换为迭代器。
fn main() {
let names = vec!["Alice", "Bob", "Cindy"];
for name in names.iter() {
print!("{} ", name)
}
println!("\nnames: {:?}", names);
// Alice Bob Cindy
// names: ["Alice", "Bob", "Cindy"]
}
Match
模式匹配类似 C switch 语句,但它更强悍一些。
fn main() {
let number = 7;
match number {
1 => println!("One"),
2 | 3 | 5 | 7 | 11 => println!("A prime"),
13..=19 => println!("A teen"),
_ => println!("Others"),
}
}
解构
match
块可以用各种方式解构项(元组、数组、枚举、结构体等等)。
fn main() {
let triple = (5, -8, 2);
match triple {
(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"),
(.., 2) => println!("last is `2` and the rest doesn't matter"),
_ => println!("It doesn't matter what they are"),
}
// last is `2` and the rest doesn't matter
}
enum Color {
Red,
RGB(u16, u16, u16),
CMYK(u32, u32, u32, u32),
}
fn main() {
let color = Color::RGB(58, 23, 78);
match color {
Color::Red => println!("The color is Red!"),
Color::RGB(r, g, b) =>
println!(
"Red: {}, green: {}, and blue: {}", r, g, b),
Color::CMYK(c, m, y, k) =>
println!(
"Cyan: {}, magenta: {}, yellow: {}, key (black): {}!",
c, m, y, k),
}
// Red: 58, green: 23, and blue: 78
}
Guard(卫语句)
卫语句 可以为匹配分支添加过滤条件。
fn main() {
let a: u8 = 58;
match a {
i if i == 0 => println!("Zero"),
i if i > 0 => println!("Greater than zero"),
_ => unreachable!("Should never happen."),
}
// Greater than zero
}
绑定
match
提供了 @
符号将值绑定到名称,这样你就可以在分支中将匹配的项作为变量使用。
fn main() {
let number = 11;
match number {
1 => println!("One"),
n @ (2 | 3 | 5 | 7 | 11) => println!("A prime: {}", n),
13..=19 => println!("A teen"),
_ => println!("Others"),
}
// A prime: 11
}
If Let
某些用例下,match
匹配略显繁琐。
let a = Some(58);
match a {
Some(b) => {
println!("My precious value is {}", b);
},
_ => {},
}
if let
在这种用例下显得更加简洁。
if let Some(b) = a {
println!("My value is {}", b);
}
While Let
while let
可以处理类似的用例。
fn main() {
let mut optional = Some(0);
while let Some(i) = optional {
if i > 9 {
println!("Hit 9, quit!");
optional = None;
} else {
println!("It's {}, try again.", i);
optional = Some(i + 1);
}
}
}
// It's 0, try again.
// It's 1, try again.
// It's 2, try again.
// It's 3, try again.
// It's 4, try again.
// It's 5, try again.
// It's 6, try again.
// It's 7, try again.
// It's 8, try again.
// It's 9, try again.
// Hit 9, quit!
代码挑战
尝试修改编辑器中提供的代码,使其打印
Greeting from John: John
。
Loading...
> 此处输出代码运行结果