先看下本篇学习内容:
通过条件来执行 或 重复执行某些代码 是大部分编程语言的基础组成部分。在Rust中用来控制程序执行流的结构主要就是 if表达式 与 循环表达式。
1. if表达式
if表达式允许我们根据条件执行不同的代码分支。我们提供一个条件,并且做出声明:“假如这个条件满足,则运行这段代码。假如条件没有被满足,则跳过相应的代码。”
举个🌰:
所有的 if表达式 都会使用 if 关键字来开头,并紧随一个判断条件。
需要注意的是,代码中的条件表达式必须产生一个 bool 类型的值,否则就会触发编译错误。
举个🌰:
这个错误表明Rust期望在条件表达式中获得一个 bool 值,而不是一个整数。与Ruby或JavaScript等语言不同,Rust不会自动尝试将非布尔类型的值转换为布尔类型。
你必须显式地在if表达式中提供一个布尔类型作为条件。假如你想要if代码块只在数字不等于0时运行,那么我们可以将if表达式修改为如下所示的样子:
1.1 使用 else if 实现多重条件判断
你可以组合 if、else 以及 else if 表达式来实现多重条件判断。例如:
当这段程序运行时,它会依次检查每一个 if表达式,并执行条件首先被判断为真的代码片段。尽管 6 可以被 2 整除,但我们既没有看到输出 number is divisible by 2,也没有看到 else 代码块中的 number is not divisible by 4, 3, or 2。
这是因为Rust会且仅会执行第一个条件为真的代码块,一旦发现满足的条件,它便不会再继续检查剩余的那些条件分支了。当然,过多的 else if 表达式可能会使我们的代码变得杂乱无章。在后面会介绍Rust中另外一个强大的分支结构语法 match,它可以被用来应对这种情况。
1.2 在let语句中使用if
由于 if 是一个表达式,所以我们可以在 let 语句的右侧使用它来生成一个值。
举个🌰:
fn main() { let condition = true; let number = if condition { 5 } else { 6 }; println!("The value of number is: {}", number);
}
记住,代码块输出的值就是其中最后一个表达式的值,另外,数字本身也可以作为一个表达式使用。
在上面的例子中,整个 if 表达式的值取决于究竟哪一个代码块得到了执行。这也意味着,所有if分支可能返回的值都必须是一种类型的。
在示例中,if 分支与 else 分支的结果都是 i32 类型的整数。假如分支表达式产生的类型无法匹配,那么就会触发编译错误,如下所示:
fn main() { let condition = true;let number = if condition { 5 } else { "six" }; println!("The value of number is: {}", number);
}
2. 使用循环重复执行代码
Rust提供了3种循环:loop、while 和 for。下面让我们来逐一讲解一下。
2.1 使用loop重复执行代码
我们可以使用 loop 关键字来指示Rust反复执行某一块代码,直到我们显式地声明退出为止。
你可以在循环中使用 break 关键字来通知程序退出循环。
2.2 从loop循环中返回值
loop 循环可以被用来反复尝试一些可能会失败的操作,比如检查某个线程是否完成了自己的工作。
不管怎么样,你也许会需要将该操作的结果传递给余下的代码。为了实现这一目的,我们可以将需要返回的值添加到break表达式后面,也就是我们用来终止循环的表达式后面。
接着,你就可以在代码中使用这个从循环中返回的值了,如下所示:
fn main() { let mut counter = 0; let result = loop { counter += 1; if counter == 10 { break counter * 2; } }; println!("The result is {}", result);
}
我们在循环前声明了变量 counter 并将其初始化为 0。接着,我们声明了一个名为 result 的变量来存储循环中返回的值。
该循环会在每次迭代时给 counter 变量中的值加 1,并检查计数器是否已经增加至 10。一旦条件符合,我们便使用 break 关键字返回 counter * 2。
在循环之后,我们还使用了一个分号来结束当前的语句,这会将循环的返回结果赋值给 result。最终,我们会打印出 result 内存储的值,在本例中,也就是 20。
2.3 while条件循环
while 会在条件为真时重复执行代码,举个🌰:
fn main() { let mut number = 3; while number != 0 { println!("{}!", number); number = number - 1; } println!("LIFTOFF!!!");
}
这段程序会循环执行3次,每次将数字减1,在循环结束后打印出特定消息并退出。
2.4 使用for来循环遍历集合
你可以使用 while 结构来遍历诸如数组之类的集合中的元素,举个🌰:
在这段程序中,代码会对数组中的所有元素进行计数。它从索引 0 开始循环,直到数组的最后一个索引(这时,条件 index < 5 不再为真)。运行这段代码会将数组中的每一个元素都打印出来。
需要指出的是,类似的代码非常容易出错,可能会因为使用了不正确的索引长度而使程序崩溃。
而且,由于我们增加了运行时的代码来对每一次遍历做出条件判断,所以这段代码的运行效率会比较低。
你可以使用 for 循环这种更简明的方法来遍历集合中的每一个元素。举个🌰:
运行这段代码,我们会看到与上上面例子同样的输出。但更重要的是,我们增强了代码的安全性,不会出现诸如越界访问或漏掉某些元素之类的问题。
for 循环的安全性和简捷性使它成为了Rust中最为常用的循环结构。即便是为了实现示例中循环特定次数的任务,大部分的Rust开发者也会选择使用 for 循环。
我们可以配合标准库中提供的 Range 来实现这一目的,它被用来生成从一个数字开始到另一个数字结束之前的所有数字序列。
arr.iter() 返回一个迭代器,它逐个访问数组中的元素。在每次循环迭代中,元素的值被赋给变量 x。
下面的代码使用了一个还未介绍过的方法 rev 来翻转 Range 生成的序列:
最后,码字不易,如果大家能给我一个赞,我也会动力满满,万分感谢你们的支持!