rust语言流程控制
流程控制
rust代码是从上至下顺序执行的,在这个过程中,可以通过循环,分支等流程控制方式来实现相应的逻辑。
if-else
rust的if-else和其它语言中的类似,但是if-else在rust中是一个表达式,并且所有分支必须返回相同的类型。下面通过例子来具体看看。
fn main() {
let a = 1;
let b = 2;
if a > b {
println!("{}", "a>b");
}else {
println!("{}", "a<=b");
}
let c = if a > b {
println!("{}", "a>b");
a
}else {
println!("{}", "a<=b");
b
}; // 当if-else表达式的值被let语句使用的时候,需要在最后加上分号,并且保证a,b返回的值是同类型。
println!("{}", c); // c的值是由if表达式执行到的分支所确定的,因此c的值是2
}
rust的条件表达式不需要使用括号包括起来。除此之外rust的if表达式还有一个if let,由于if let本质上是和match一样的模式匹配,不在此处描述。
使用else if处理多重条件
和其它语言类似,rust的if-else语句可以有大量的分支用来处理多重条件。例如:
fn main() {
let n = 6;
if n % 4 == 0 {
println!("number is divisible by 4");
} else if n % 3 == 0 {
println!("number is divisible by 3");
} else if n % 2 == 0 {
println!("number is divisible by 2");
} else {
println!("number is not divisible by 4, 3, or 2");
}
}
程序执行时,会按照自上至下的顺序执行每一个分支判断,一旦成功,则跳出 if 语句块,最终本程序会匹配执行 else if n % 3 == 0 的分支,输出 “number is divisible by 3”。有一点要注意,就算有多个分支能匹配,也只有第一个匹配的分支会被执行!(例如这段代码中的number is divisible by 2虽然匹配成功,但是不会被执行。)
for循环
rust的for循环和python,javascript的for循环看起来很像,语义如下:
for 元素 in 集合 {
// 使用元素
}
注意,使用 for 时我们往往使用集合的引用形式,这能避免集合的所有权转移。(除非你之后不再使用该集合),如果是实现了Copy trait的数组,那么不会导致所有权的转移。如果想在循环中,修改该元素,可以使用mut关键字。例如:
for num in &mut nums { // 可变引用,修改元素的值
*num += 3; // 注意这里需要手动解引用,
}
println!("{:?}", nums);
获取元素索引
在循环中获取元素的索引,可以使用下面的方式。
for (i, v) in nums.iter().enumerate() {
println!("第{}个元素是{}", i, v);
}
下表是可变引用,不可变引用,转移所有权的等价使用方式。
使用方法 | 等价使用方式 | 所有权 |
---|---|---|
for item in collection | for item in IntoIterator::into_iter(collection) | 转移所有权 |
for item in &collection | for item in collection.iter() | 不可变借用 |
for item in &mut collection | for item in collection.iter_mut() | 可变借用 |
for循环能够对迭代器进行循环迭代。(正如上面表格中的等价形式一样,for是对迭代器进行的。) |
控制循环执行次数
下面是一个使用for循环控制循环体执行10次的例子。
for i in 0..10 {
println!("{}", i);
}
如果你不需要使用i,那么可以使用_来代替。在 Rust 中 _ 的含义是忽略该值或者类型的意思,如果不使用 _,那么编译器会给你一个 变量未使用的 的警告。例如:
for _ in 0..=10 {
println!("Hello rust!");
}
continue
和其它编程语言一样,continue都是跳过本次循环,开始下次循环。例如:
for i in 0..=10{
if i % 2 == 0 {
continue;
}
println!("{}", i);
}
程序执行结果如下所示:
1
3
5
7
9
break
和其它编程语言一样,break可以跳出整个循环,使当前循环结束。例如:
for i in 1..9 {
if i == 5 {
break;
}
println!("{}", i);
}
程序执行结果如下所示:
1
2
3
4
while循环
while循环相比for循环,可能没有那么常用。当循环条件为 true 时,继续循环,条件为 false,跳出循环。例如:
let mut count = 0;
while count < 3 {
println!("{}", count);
count += 1;
}
loop循环
rust提供了loop循环,它是一个简单的无限循环。因此在使用loop循环的时候要格外小心,如果你忘记配合break来使用,那程序可能就在循环里永远出不来了。另外一点是loop循环是一个表达式,而for和while循环不是。例如:
let result = loop {
count += 1;
if count == 10 {
break count * 2;
}
};
println!("{}", result);
这段代码中,通过break带回了返回值。打印出20
循环标签
和大多数语言一样,再存在多层循环嵌套的情况下,break 和 continue 应用于此时最内层的循环。rust提供了标签结合continue,break来使用,使这些标签应用于已标记的循环而不是内层的循环。例如:
fn main() {
let mut count = 0;
'outer: loop {
'inner1: loop {
if count >= 20 {
// 这只会跳出 inner1 循环
break 'inner1; // 这里使用 `break` 也是一样的
}
count += 2;
}
count += 5;
'inner2: loop {
if count >= 30 {
break 'outer;
}
continue 'outer;
}
}
assert!(count == 30)
}
这段代码需要仔细看,不能大意。因为有的break和continue是跳到某一个标签,而不是最内层的循环。循环标签使得循环更加强大,但是带来的后果是使得代码的逻辑变得更加复杂难懂。非必要不使用循环标签。
参考资料
相关文章
- 在 Go 里用 CGO?这 7 个问题你要关注!
- 9款优秀的去中心化通讯软件 Matrix 的客户端
- 求职数据分析,项目经验该怎么写
- 在OKR中,我看到了数据驱动业务的未来
- 火山引擎云原生大数据在金融行业的实践
- OpenHarmony富设备移植指南(二)—从postmarketOS获取移植资源
- 《数据成熟度指数》报告:64%的企业领袖认为大多数员工“不懂数据”
- OpenHarmony 小型系统兼容性测试指南
- 肯睿中国(Cloudera):2023年企业数字战略三大趋势预测
- 适用于 Linux 的十大命令行游戏
- GNOME 截图工具的新旧截图方式
- System76 即将推出的 COSMIC 桌面正在酝酿大变化
- 2GB 内存 8GB 存储即可流畅运行,Windows 11 极致精简版系统 Tiny11 发布
- 迎接 ecode:一个即将推出的具有全新图形用户界面框架的现代、轻量级代码编辑器
- loongarch架构介绍(三)—地址翻译
- Go 语言怎么解决编译器错误“err is shadowed during return”?
- 敏捷:可能被开发人员遗忘的部分
- Denodo预测2023年数据管理和分析的未来
- 利用数据推动可持续发展
- 在 Vue3 中实现 React 原生 Hooks(useState、useEffect),深入理解 React Hooks 的