7、初识Rust – 控制流
控制流是大部分编程语言的基本组成部分。Rust代码中最常见的控制程序执行流的结构就是 if 表达式和循环。
一、if表达式
if表达式根据条件来执行不同的代码分支,代码中的条件必须是 bool 值。如果不是bool值,Rust就会抛出错误。这和部分编程语言,比如javascript不一样,Rust不会尝试将非bool值转换为bool值。
fn main() { let a = 2; if a > 1 { println!(">1"); } else { println!("<1"); } }
例如上面这段代码,条件检查变量a是否大于1,如果大于1就执行紧跟在条件后的表达式打印 “>1” 如果小于1,就执行else后的表达式打印 “<1″。esle表达式用来提供条件为假时执行的代码块。
Rust可以和大多数编程语言一样,使用else if表达式与if else表达式实现多重条件。
fn main() { let a = 4; if a == 1 { println!("a等于1"); } else if a == 2 { println!("a等于2"); } else if a == 3 { println!("a等于3"); } else { println!("a不等于1,2,3"); } }
例如上面这段代码,它按顺序检查每个 if 表达式并执行第一个条件为真的代码块。一旦找到为真的代码块后,就不会在检查后续的代码块。
前面说到if与else都是一个表达式,所以我们可以在let中使用它并获得返回值。
fn main() { let a = 1; let b = if a > 1 { 3 } else { 4 } println!("{b}"); }
但是要特别注意,返回值类型需要相同,否则就会抛出错误。
二、循环
在实际应用中,多次执行同一段代码的需求非常常见。Rust提供了多种循环。
Rust有三种循环,分别是 loop、while、for。
1、loop
loop循环告诉Rust,一直循环一段代码,直到你发出停止指令。
fn main() { loop { println!("loop"); } }
上面这个例子,就会无限打印 loop直到你手动(ctrl-c)结束。
当然,Rust也提供了手动结束loop循环的命令。
fn main() { let mut i = 0; loop { if i == 10 { println!("{i}"); break; }else{ println!("{i}"); i = i + 1; } } }
上面这个例子,就是loop循环,并在每次循环时对i进行判断,如果没有等于10,那么就对i进行一个递增操作,如果等于10那么就使用break跳出loop循环。
fn main() { let mut a = 0; loop { if a == 10 { println!("{a}"); continue; } else { println!("{a}"); a = a + 1; } } }
上面这个例子,在循环递增a后,如果判断a == 10,则使用continue跳过该次循环,进行下一次循环。如果你运行上面这段代码,你就会发现,输出0 – 9后,接下去就会无限打印 10。
loop其中一个用法是检查可能会失败的操作,比如检查线程是否完成了任务,这种情况下,你可能需要将结果传递给其它代码。这时就可以将值放在表达式break后面即可。
fn main() { let mut a = 0; let b = loop { if a == 10 { break a * 10; } else { a = a + 1; } }; println!("{b}"); }
要注意的是,这次的返回需要加上分号。
除了单层的loop外,我们也可以进行多层嵌套。
fn main() { let mut a = 0; 'test: loop { let mut b = 0; println!("a: {a}"); loop { if b == 5 { println!("b: {b}"); break; } if a == 3 { break 'test; } b = b + 1; } a = a + 1; } println!("结束 a: {a}"); } a: 0 b: 5 a: 1 b: 5 a: 2 b: 5 a: 3 结束 a: 3
需要注意的是,如果是嵌套循环,break与continue应该在最内层的循环。我们可以手动指定一个循环标签,例如上面代码中的 ‘test,然后将标签与 break 和 continue一起使用。使这些关键字应用对相对层的loop 生效,而不是最内层。
2、while条件循环
while条件循环可以判断条件是否满足,条件为false时停止循环,条件为true时继续循环。这个功能使用loop + if + else表达式也可以实现,但是复杂度会提升不少,所以就有了while这个循环。
fn main() { let mut a = 10; while a != 0 { println!("{a}"); a = a - 1; }; println!("完成!"); } 10 9 8 7 6 5 4 3 2 1 完成!
这种结构消除了很多使用 loop
、if
、else
和 break
时所必须的嵌套,这样更加清晰。当条件为真就执行,否则退出循环。可以使用while来遍历集合中的元素,比如数组。
fn main() { let a = [1; 10]; let mut index = a.len() - 1; while index != 0 { println!("{}",a[index]); index = index - 1; }; println!("完成!"); }
不过这个过程会使程序运行变慢,同时也不够简洁。for是更简洁的一个替换方案。
3、for循环
前面说到for在遍历元素时时while一个非常好的替换方案。
fn main() { let a = [1; 10]; for ele in a { println!("{ele}") } println!("完成!"); }
如上面代码,可以遍历a数组并将每个值输出。for循环的安全性和简洁性使它成为了Rust中使用最多的循环结构,即使想要循环执行代码特定次数时,也会使用for循环,如下程序。
fn main() { for i in {1..16}.rev() { println!("{i}") } println!("完成!"); }