LetRust

控制流

根据条件是否为真来控制是否执行某段代码

if 表达式

if 运行代码根据不同的条件执行不同的分支逻辑。当提供的表达式满足对应的条件,则代码运行,否则将跳过

    let num = 3;
    if num < 5 {
        println!(" num :  {} 小于 5", num);
    } else {
        println!(" num :  {} 大于 5", num);
    }

在上面的代码示例中,条件表达式检查变量 num 是否小于 5,如果小于 5 则执行 println!(" num : {} 小于 5", num) 否则执行 println!(" num : {} 大于 5", num)

有一点需要注意,在条件判断表达式中,所有的条件必须是 bool,如果条件不是 bool 类型,那么 Rust 将会抛出错误。

$ cargo run
   Compiling branches v0.1.0 (file:///projects/branches)
error[E0308]: mismatched types
 --> src/main.rs:4:8
  |
4 |     if number {
  |        ^^^^^^ expected `bool`, found integer

For more information about this error, try `rustc --explain E0308`.
error: could not compile `branches` (bin "branches") due to 1 previous error

在上面的错误中,我们可以明显的看到,Rust 期望一个bool类型作为条件表达式的依据,但是却得到了一个整数,这个是错误的。

//在C/C++ 或一些其他语言中,经常能看到下面的代码,熟悉c++的小伙伴们一定比较熟悉这种操作,这里就不再过多赘述
#include <iostream>
int main() {
    int isActive=1;
    if (isActive) {
        std::cout << "条件满足,执行相关操作..." << std::endl;
    }
    return 0;
}
else if 多条件处理

如果出现多种条件,可以使用 else if 这种语义结构实现逻辑分支控制

fn main() {
    let number = 6;

    if number % 4 == 0 {
        println!("number is divisible by 4");
    } else if number % 3 == 0 {
        println!("number is divisible by 3");
    } else if number % 2 == 0 {
        println!("number is divisible by 2");
    } else {
        println!("number is not divisible by 4, 3, or 2");
    }
}

在上面的代码中,程序会从上开始执行,逐个分支进行判断,一旦命中逻辑,则执行对应分支中的代码,结束当前方法。

结合 let 使用 if else 语句

这个操作在我理解有些像 三元表达式 语法有些像 python ,下面是一个示例

    let condition = true;
    let number = if condition { 5 } else { 6 };

    println!("The value of number is: {number}");

这里让我们来拆解下这段代码:

第一行:定义了一个 bool 类型的变量,名称为 condition 第二行:定义了一个结果,number 接收 表达式 if condition { 5 } else { 6 } 的结果 第三行:打印输出结果

在第二行的代码可以转换成下面的样子,就变成了上面的 if else结构

if(condition){
  number = 5;
} else {
  number = 6;
}
为什么不需要写 number = 5 ?

因为在代码块中,分支中的数字本身就被当成了一个表达式,让我们回想 3.3 function返回值的描述,其中提到了,最后一行是不要写 return; 的。所以结合if condition { 5 } else { 6 }表达式的内容。就可以理解为,当条件成立的时候,返回 5 不成立返回 6。

注意:在这种包含 let 的表达式中,返回的数据类型必须一致。

循环

loop

loop 关键字可以重复执行一段代码,直到 Rust 明确的知道需要停止,才会停止

下面的例子就是一个循环执行的逻辑

fn control_loop() {
    let mut count = 0;

    loop {
        if count > 3 {
            break;
        }
        count = count + 1;
        println!("control_loop count >>> {count}");
    }
}

这个例子的输出

control_loop count >>> 1
control_loop count >>> 2
control_loop count >>> 3
control_loop count >>> 4

让我们来分析下这段代码干了些什么事情...

代码中定义了一个可以更改的变量 count 设置初始值为 0。紧接着进入 loop循环体中,在循环体中判断count的大小,当count大于 3的时候使用 break关键字终止循环,避免程序进入死循环(记住在任何时候都要避免写死循环的代码,即使是一个需要定时轮询的任务也尽量避免,这个很危险!),判断逻辑结束后,开始对count累加,意思是每循环一次,count+1,每次循环打印输出的信息。

在方法 control_loop 中,一共执行了4次,所以才有了上面的输出内容。通过这个例子,我们能大概理解 loop做了件什么事情。

那我们是否可以在loop中返回一个结果呢?答案是可以的,来看下面的代码

fn control_loop_result() {
    let mut count = 0;
    let result = loop {
        count += 1;
        if count == 10{
            break count * 5;
        }
    };
    println!("control_loop_result >> result >> {result}")
}

在上面的代码中,我们可以使用 break count * 5; 这样的形式将结果直接返回到 result 变量中。

嵌套循环和标签

如果存在嵌套循环,breakcontinue 应用于此时最内层的循环。你可以选择在一个循环上指定一个 循环标签(loop label),然后将标签与 breakcontinue 一起使用,使这些关键字应用于已标记的循环而不是最内层的循环。下面是一个包含两个嵌套循环的示例:

fn control_loop_tag() {
    let mut count = 0;
    'counting_up: loop {
        println!("count = {count}");
        let mut remaining = 10;

        loop {
            println!("remaining = {remaining}");
            if remaining == 9 {
                break;
            }
            if count == 2 {
                break 'counting_up;
            }
            remaining -= 1;
        }

        count += 1;
    }
    println!("End count = {count}");
}

外层循环有一个标签 counting_up,它将从 0 数到 2。没有标签的内部循环从 10 向下数到 9。第一个没有指定标签的 break 将只退出内层循环。break 'counting_up; 语句将退出外层循环。这个代码打印:

count = 0
remaining = 10
remaining = 9
count = 1
remaining = 10
remaining = 9
count = 2
remaining = 10
End count = 2
while

while循环和loop基本上一样,就是while有个显式的条件来判断程序是否需要停止执行。

    let a = [10, 20, 30, 40, 50];
    let mut index = 0;

    while index < 5 {
        println!("the value is: {}", a[index]);

        index += 1;
    }

在通常的语境中,whileloop都被用来处理不知道需要迭代多久的逻辑。

for

for 是已知需要循环的次数,在一些遍历已知长度的队列、数组等场景,for是很常用的。

    for number in (1..4).rev() {
        println!("{number}!");
    }
    println!("LIFTOFF!!!");
🔙上一页 第四章🔜