控制流
根据条件是否为true来决定是否执行某段代码,或者循环执行某段代码。Rust中常见的控制流有:if表达式、循环、模式匹配(match)。
if 表达式
1. if 表达式的特征
- if 表达式当条件为true时就执行表达式内的代码,否则就不执行。
- if 表达式可选地组合else,顺序地执行后续的代码。
- if 表达式的判断条件必须为 bool 类型(返回 bool 类型的函数等),因为rust不会隐式地转换数据地类型。
- if、else if可用于多重条件判;需要注意的是,Rust 只会执行第一个条件为真的代码块。当某一个分支的条件满足后,即使后续分支的条件也满足,也不会再执行其它代码块了。
rust
fn main(){
//判断条件必须为bool类型
if 6 > 0 {
println!("{}",true)
}
if is_alter(6) {
println!("{}",true)
}
else {
println!("{}",false)
}
//多重判断,第一个分支满足条件了,所以只会输出“fisrt arm”,后续的分支不会再执行了
if is_alter(10) {
println!("fisrt arm")
}else if is_alter(6) {
println!("second arm")
}else {
println!("no match arm")
}
}
pub fn is_alter(num:i32) -> bool{
num > 5
}
2. 在 let 语句中使用 if
- if 是一个表达式,所以可以在 let 语句的右侧使用它来将结果赋值给一个变量。
- if...else的每个分支的可能的返回值都必须是
相同类型
,因为rust在 编译时期就要准确地知道每个变量地类型,就可以在编译时验证在每处使用的 number 变量的类型是有效的。
rust
fn main(){
let condition:bool = true;
//if的每个分支都必须返回相同的类型
let number = if condition { 5 } else { 4 };
println!("number is {}",number);
//返回不同的类型时,会触发panic:expected integer, found `&str`
// let x = if condition { 5 } else { "SIX" };
// println!("number is {}",x);
}
循环
循环是指遍历执行循环体中的代码直至结尾,然后再回到开头重新执行。Rust提供了多种循环:loop
、while
、for
等。
1. loop循环
无限循环执行表达式里的代码块,直至你要求停止。
rust
fn main(){
loop{
println!("hello,world");
}
}
上面的代码会不断地在控制台打印hello,world,直到我使用 Ctrl + C来终止程序。
2. while条件循环
条件为真,执行循环。当条件不再为真,调用 break
停止循环。
rust
fn mian(){
let mut x = 3;
while x != 0{
println!("x is {}",x);
x -= 1;
}
println!("hello,world")
}
上面的while循环会执行三次,这时x变成0,条件判断为false,调用break终止循环,然后打印hello,world结束程序。
3. for 循环遍历集合
使用while循环也可以遍历合集的元素,通过将判断条件设定问集合索引的边界实现循环访问。
rust
fn main(){
let x = [1,2,3,4,5];
let mut index = 0;
while index < 5{
println!("第{}个元素是:{}",index,x[index])
}
}
shell
第0个元素是:1
第1个元素是:2
第2个元素是:3
第3个元素是:4
第4个元素是:5
index
在某一时刻会到达值 5
,不过循环在其尝试从数组获取第 6 个值:x[5](会越界)之前就停止了。如果索引值或测试条件不正确会导致程序 panic,
这使程序更慢,因为编译器增加了运行时代码来对每次循环进行条件检查,以确定在循环的每次迭代中索引是否在数组的边界内。
更简洁的替代方案是for
循环:
rust
fn main(){
for i in x {
println!("第{}个元素是:{}",i,i);
}
}
shell
第1个元素是:1
第2个元素是:2
第3个元素是:3
第4个元素是:4
第5个元素是:5
与while遍历集合不同的是,for循环直接遍历集合的元素,而不是借助索引,这很好地避免了集合的边界问题。
4. 循环标签、continue、break
- 使用
'labelName:
标识loop,这个名字就叫做 “循环标签” 。 break
关键字来告诉程序何时停止循环。continue
关键字告诉程序跳过当前迭代中的任何剩余代码,并转到下一个迭代。
rust
fn main(){
let mut x = 0;
'outer:loop{
println!("x is {}",x);
let mut z = 10;
'inner:loop{
println!("z is {}",z);
if z == 9 {
break 'inner ;
}
if x == 2 {
break 'outer;
}
z -= 1;
}
x += 1;
}
}
上述代码为双层嵌套的loop循环,执行流程如下:
inner loop
执行一次使 z = 9 后,满足第一个 if 条件,被break跳出。回到outer loop
继续执行后续代码,x变为1,进入outer loop
的下一次迭代,z被重新声明为10。- 进入
inner loop
,重复执行步骤一,差异是,这时x变为2,然后进入outer loop
的下一个迭代,最终进入inner loop
,这时第二个 if 条件被满足,跳出``outer loop`,至此程序结束。
shell
x is 0
z is 10
z is 9
x is 1
z is 10
z is 9
x is 2
z is 10
rust
fn main() {
let mut count = 0;
while count < 10 {
count += 1;
if count % 2 == 0{
continue;
}
println!("count is {}",count)
}
}
上述代码中当 count 整除2时,就使用continue
跳出当前迭代,因此当前迭代后续的 println
代码就不会执行了。
shell
count is 1
count is 3
count is 5
count is 7
count is 9
模式匹配
模式匹配需要用到枚举相关知识,后续再讨论。