开发环境
- Windows 10
- Rust 1.53.0
- VS Code 1.58.2
项目工程
这里继续沿用上次工程rust-demo
Rust的流程控制
在大多数编程语言中,决定是否运行某些代码取决于条件是否为真,并决定在条件为真时重复运行一些代码。让编码者控制Rust代码执行流程的最常见构造是if表达式和循环。
条件语句
if表达式
if表达式允许编码者根据条件将代码分支。提供一个条件,然后状态,“如果满足此条件,请运行此代码块。如果条件未满足,请不要运行此代码块。”
在工程目录中创建一个名为分支的新项目,以探索if表达式。示例如下:
fn main() {
let number = 3;
// if表达式
if number < 5 {
println!("condition was true");
} else {
println!("condition was false");
}
}
所有if表达式都以关键字if开头,后面跟着一个条件。
另外,我们还可以包括一个其他表达式,我们选择在这里这样做,以便在条件计算为false时给程序一个可选的代码块来执行。如果不提供其他表达式,且条件为false,则程序将跳过if块,然后转到下一段代码。
我们运行上述代码。
cargo run
结果:
如果修改代码:
fn main() {
let number = 7;
// if表达式
if number < 5 {
println!("condition was true");
} else {
println!("condition was false");
}
}
再运行
if...else if表达式
也可以通过将if和else组合到一个else if表达式中,从而具有多个条件。
示例如下:
fn main() {
let number = 6;
// if表达式
if number % 4 == 0 {
println!("number is divisible by 4");
} else if number % 3 == 0 { // else if表达式
println!("number is divisible by 3");
} else if number % 2 == 0 { // else if表达式
println!("number is divisible by 2");
} else { // else表达式
println!("number is not divisible by 4, 3, or 2");
}
}
运行结果:
在let语句中使用if
因为如果是表达式,我们可以在let语句的右侧使用它。示例如下:
fn main() {
let condition = true;
// if后面判断condition的值,如果为真,则number为5,否则为6
let number = if condition { 5 } else { 6 };
println!("The value of number is: {}", number);
}
运行结果:
如果将上述代码修改为:
fn main() {
let condition = true;
// 编译时这里会报错,不同数据类型做判断
let number = if condition { 5 } else { "six" };
println!("The value of number is: {}", number);
}
运行
if代码块中的表达式计算为整数,其他块中的表达式计算为字符串。这不起作用,因为变量必须只有一个类型,Rust需要在编译时知道数字变量是什么类型,所以它可以在编译时验证它的类型是否有效,无论我们在哪里使用数字。如果只有在运行时才确定数字的类型,Rust就无法做到这一点;编译器将更加复杂,如果它必须跟踪任何变量的多个假设类型,那么对代码的保证就会更少。
循环
多次执行代码块通常是有用的。对于这个任务,Rust提供了几个循环。循环通过循环体内的代码一直运行到末尾,然后在开始时立即返回。
Rust有三种循环:loop,while,和for。
loop循环
loop关键字告诉Rust一次又一次地执行一段代码,或者直到您显式地告诉它停止。
示例:
fn main() {
// 循环loop
loop {
println!("again!");
}
}
运行
当我们运行这个程序时,我们看到again!一遍又一遍地打印,直到我们手动停止程序。大多数终端支持键盘快捷键ctrl-c来中断处于连续循环中的程序。
符号^C表示按ctrl-c的位置。你可能会也可能不会再看到这个词!打印在^C之后,这取决于它接收中断信号时循环中代码的位置。
幸运的是,Rust提供了另一种更可靠的方法来打破循环。您可以在循环中放置break关键字,以告诉程序何时停止执行循环。
break语句
loop的一个用途是重试您知道可能失败的操作,例如检查线程是否已完成其任务。但是,您可能需要将该操作的结果传递给您的其余代码。为此,您可以在停止循环的break表达式之后添加希望返回的值;该值将从循环中返回,以便您可以使用它。示例:
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
// break表达式,当counter值为10的时候,将counter乘2的值赋值给result,退出循环
if counter == 10 {
break counter * 2;
}
};
println!("The result is {}", result);
}
运行
条件循环while
对于程序来说,评估循环中的条件通常是有用的。条件为真时,循环运行。当情况不再真实时,程序调用break,停止循环。这个循环类型可以使用组合来实现loop,if,else和break。
然而,这种模式非常常见,以至于Rust有一个内置的语言构造,称为while循环。示例:
fn main() {
let mut number = 3;
// while循环
while number != 0 {
println!("{}!", number);
number -= 1;
}
println!("LIFTOFF!!!");
}
这个构造消除了很多嵌套,如果您使用loop,if、else和break,那么嵌套就更清楚了。当条件保持为真时,代码就会运行;否则,它退出循环。
下面我们看while循环的另一个示例。
fn main() {
// 定义数组
let a = [10, 20, 30, 40, 50];
// 数组下标
let mut index = 0;
// while循环
while index < 5 {
// 打印数组中的元素值
println!("the value is: {}", a[index]);
index += 1;
}
}
运行结果
但是这种方法容易出错;如果索引长度不正确,我们可能会引起程序的恐慌。这也很慢,因为编译器添加了运行时代码,以便在循环中对每个迭代中的每个元素执行条件检查。
for循环
作为一种更简洁的选择,可以使用for循环并对集合中的每个项执行一些代码。
可以将上述代码修改为:
fn main() {
let a = [10, 20, 30, 40, 50];
// for循环
for element in a.iter() {
println!("the value is: {}", element);
}
}
运行结果
运行结果和while循环的代码结果一致。更重要的是,我们现在已经提高了代码的安全性,并且消除了错误的可能性,这些错误可能是因为超出数组的末尾而导致的,或者是不够远的,并且丢失了一些项。
for循环的安全性和简洁性使其成为Rust中最常用的循环结构。Rust中,个人推荐使用for循环。这样做的方法是使用一个range,它是由标准库提供的一种类型,它按顺序从一个数字开始生成所有数字,在另一个数字之前结束。
for循环的另一个示例:
fn main() {
// 反序输出1到4中的元素:3,2,1
for number in (1..4).rev() {
println!("{}!", number);
}
println!("LIFTOFF!!!");
}
运行结果
本章重点
- 条件判断:if,if...else,if...else if...else
- 循环:loop,while,for