【RUST学习日记】第17课 流程控制

简介: 【RUST学习日记】第17课 流程控制

0x00 回顾与开篇


有关Rust数据类型的知识暂时告一段落了,从这节开始讲解Rust中的流程控制。在Rust中控制代码执行流程有两种方式——条件判断和循环。


0x01 条件判断


if表达式在任何语言里面都很常见,其形式如下:

if condition1 {
    block1
} else if condition2 {
    block2
} else {
    block3
}

所有的condition都是一个bool型的表达式。Rust并不像C语言那样,非0值表示true,0值表示falsecondition的花括号并不是必须的。


下面通过一道题来练习下:求一个数对应的星期。将一个数对7取余,如果是0,则选择的是周日,以此类推,如果是6则选择的是周6。


示例代码如下:

// 求一个数对应的星期。将一个数对7取余,如果是0,则选择的是周日,以此类推,如果是6则选择的是周6
    let week: u32 = 1;
    if week % 7 == 0 {
        println!("您选择的是周日!")
    } else if week % 7 == 1 {
        println!("您选择的是周一!")
    } else if week % 7 == 2 {
        println!("您选择的是周二!")
    } else if week % 7 == 3 {
        println!("您选择的是周三!")
    } else if week % 7 == 4 {
        println!("您选择的是周四!")
    } else if week % 7 == 5 {
        println!("您选择的是周五!")
    } else {
        println!("您选择的是周六!")
    }

代码运行结果如下:

您选择的是周一!


0x02 循环


循环,顾名思义,表示重复执行某一段代码。在Rust中,共有3中循环形式,分别是loop,while,for..in..循环。控制循环的语句有两个:break和continue。


break和continue


break和continue都用来循环控制。break用于直接退出循环,continue则表示跳出当前轮次的循环,不在执行continue后的代码,但是它仍然会再次执行调节判断,决定是否执行下次循环。


loop循环


重复执行,永远不会结束,如果没有退出条件,那就是死循环了。使用起来比较简单。

其签名形式为:

loop {
// 要执行循环的代码
}

示例代码如下:

let mut count = 0;
    loop {
        count += 1;
        // 计数器为5则跳出循环
        if count == 5 {
            break;
        }
    }
    println!("count = {}", count);

代码运行结果:

loop循环 -> count = 5


while循环


while后面跟一个表达式,如果表达式的值为true,则会执行循环。


示例代码如下:

let mut count = 0;
    while count < 5 {
        count += 1;
    }
    println!("while循环 -> count = {}", count);

代码运行结果:

while循环 -> count = 5


for..in..循环


重复执行指定次数的循环。


示例代码如下:

let mut count = 0;
    for i in 1..=5 {
        count = i
    }
    println!("for..in..循环 -> count = {}", count);

代码运行结果:

for..in..循环 -> count = 5

前面示例代码都是用break来做示例的,接下来练习下continue的用法。看下下面的代码运行后,count的最终结果是多少呢?

示例代码如下:

let mut count = 1;
    while count < 5 {
        if count % 2 == 0 {
            count += 5;
            continue;
        }
        count += 1;
    }

代码运行结果:

continue test -> count = 7

解释:


代码开始,count赋值为1,然后经过while循环,当count < 5执行循环。

循环体内,如果count % 2 == 0,执行条件代码块。当然,第一次循环count == 1,显然count % 2 != 0 不满足条件,继续执行count += 1,得到count == 2

第二次循环,count == 2,满足count % 2 == 0,执行 count += 5,得到count == 7,然后continue,不再执行循环体内下面的代码,转而执行第三次循环。

第三次循环,count == 7,不满足count < 5这个条件,退出循环,输出count的值为7。 


0x03 match模式匹配


match


在Rust中,并没有其它语言的switch语句,取而代之的是match模式匹配。match用来判断当前值是否匹配一系列模式中的某一个。模式可以由字面量,变量,通配符来构成。与其它语言中的switch的类似,每一个模式即是一个分支。


PS:在Rust中,match模式匹配要求穷举所有的可能性,否则会导致程序报错。可以在一系列模式最后添加_通配符,表示没有指定的其它所有模式(相当于Java中的default)。

示例代码如下(将第一个示例转为match实现):


// 求一个数对应的星期。将一个数对7取余,如果是0,则选择的是周日,以此类推,如果是6则选择的是周6
    let week: u32 = 6;
    match week % 7 {
        0 => { println!("您选择的是周日!") }
        1 => { println!("您选择的是周一!") }
        2 => { println!("您选择的是周二!") }
        3 => { println!("您选择的是周三!") }
        4 => { println!("您选择的是周四!") }
        5 => { println!("您选择的是周五!") }
        6 => { println!("您选择的是周六!") }
        _ => { println!("未知!") }
    }

代码运行结果:

您选择的是周六!


if let 和 while let


在某些场合使用match可能会显得有些繁琐,因此在Rust中也提供了if letwhile let在某些场景下替换match

if let

if let的形式如下:

if let pattern = expr {
 block1
} else {
 block2
}

使用if let进行匹配时要注意,patternexpr直接是单=号。还是拿本章开始的那个例子来解释,假设我只是想对周五这一天做匹配妖气,而对其它没有任何要求,我们就可以使用if let进行改造。

示例代码如下:

let week: u32 = 5;
    if let 5 = week % 7 {
        println!("您选择的是周五!");
    } else {
        println!("未知!");
    }

代码运行结果:

您选择的是周五!

while let

while let的形式如下:

while let pattern = expr {
    block
}

现在有个要求需要逆向依次输出向量中的值。

使用loop和match实现:

let mut vec = vec![1, 3, 5, 7, 9];
    loop {
        match vec.pop() {
            None => {
                break;
            }
            Some(value) => {
                print!("{} ", value);
            }
        }
    }

改造为while let:    

let mut vec = vec![1, 3, 5, 7, 9];
    while let Some(value) = vec.pop() {
        print!("{} ", value);
    }

代码运行结果:

match loop:
9 7 5 3 1 
while let:
9 7 5 3 1

显而易见,经过while let改造过的代码显得比较简洁。这其实感觉就像是Rust给我们的语法糖。 


0x04 小结


本节介绍了流程控制,循环,match匹配。最后还介绍了使用while let和if let在某些场景下可以简化代码。相比较而言,这节课还是比较简单和轻松的。

相关文章
|
12天前
|
存储 Rust 网络协议
【Rust学习】10_定义枚举
在这一章我们学习 枚举(enumerations),也被称作 enums。枚举允许你通过列举可能的 成员(variants) 来定义一个类型。首先,我们会定义并使用一个枚举来展示它是如何连同数据一起编码信息的。接下来,我们会探索一个特别有用的枚举,叫做 Option,它代表一个值要么是某个值要么什么都不是。然后会讲到在 match 表达式中用模式匹配,针对不同的枚举值编写相应要执行的代码。最后,我们将学习 if let 结构,另一个简洁方便处理代码中枚举的结构。
29 7
|
1月前
|
Rust 算法 安全
学习Rust
【10月更文挑战第13天】学习Rust
53 8
|
1月前
|
Rust 安全 算法
Rust的学习
【10月更文挑战第12天】Rust的学习
28 2
|
1月前
|
Rust 算法 安全
如何学习Rust编程?
【10月更文挑战第12天】如何学习Rust编程?
42 1
|
1月前
|
Rust API
【Rust学习】09_方法语法
结构体让你可以创建出在你的领域中有意义的自定义类型。通过结构体,我们可以将相关联的数据片段联系起来并命名它们,这样可以使得代码更加清晰。在 impl 块中,你可以定义与你的类型相关联的函数,而方法是一种相关联的函数,允许您指定结构体的实例具有的行为。 但是结构体并不是创建自定义类型的唯一方式:让我们转向 Rust 的 enum 功能,将另一个工具添加到你的工具箱中。
17 0
|
2月前
|
Rust 索引
【Rust学习】08_使用结构体代码示例
为了了解我们何时可能想要使用结构体,让我们编写一个计算长方形面积的程序。我们将从使用单个变量开始,然后重构程序,直到我们改用结构体。
92 2
|
2月前
|
存储 Rust 编译器
【Rust学习】07_结构体说明
**struct**或 ***structure***是一种自定义数据类型,允许您命名和包装多个相关的值,从而形成一个有意义的组合。如果您熟悉面向对象的语言,那么**struct**就像对象中的数据属性。在本章中,我们将比较和对比元组与结构体,在您已经知道的基础上,来演示结构体是对数据进行分组的更好方法。
26 1
|
3月前
|
存储 Rust 安全
【Rust学习】06_切片
所有权、借用和切片的概念确保了 Rust 程序在编译时的内存安全。Rust 语言提供了跟其他系统编程语言相同的方式来控制你使用的内存,但拥有数据所有者在离开作用域后自动清除其数据的功能意味着你无须额外编写和调试相关的控制代码。
26 1
|
2月前
|
Rust Linux Go
Rust/Go语言学习
Rust/Go语言学习
|
4月前
|
存储 Rust 安全
【Rust学习】04_所有权
所有权是 Rust 最独特的特性,对语言的其余部分有着深远的影响。它使 Rust 能够在不需要垃圾收集器的情况下保证内存安全,因此了解所有权的运作方式非常重要。在本章中,我们将讨论所有权以及几个相关功能:借用、切片以及 Rust 如何在内存中布局数据。
27 1