NexaGrid技术博客

NexaGrid技术博客

二、Rust从基础到实战应用(流程控制)

12
2025-06-25
二、Rust从基础到实战应用(流程控制)

本章将会介绍Rust中的流程控制:

  1. 条件判断: if , if-elseif-else if-else

  1. 循环: loop, whilefor

  2. 模式匹配: match, if letwhile let

1. 条件判断

条件判断是根据条件表达式的值是否为true来决定是否决定执行某段代码。

1.1 if

if age > 18 {
  println!("You are an adult.");
}

1.2 if-else

if age > 18 {
  println!("You are an adult.");
}else {
  println!("You are not an adult.");
}

1.3 if-else if-else

if age < 1 {
  println!("You are a baby.");
}else if age < 18 {
  println!("You are not an adult.");
} else {
  println!("You are not an adult.");
}

2. 循环

循环是指根据条件表达式的值是否为true来决定是否重复执行某段代码。

2.1 loop

重复执行,永不结束的循环。需要使用break或者return主动跳出循环,break x等于跳出循环并且返回值。

fn main() {
  let mut count = 0;
  let counter = loop {
    count += 1;
    let counter = count * 2;
    
    if count == 10 {
      break counter;
    }
}

2.2 while

当满足循环表达式=true时,重复执行。

fn main() {
  let mut count = 0;
  while count != 10 {
    count += 1;
    let counter = count * 2;
    
    if count == 10 {
      break counter;
    }
}

2.3 for

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

fn main() {
  let mut count = 0;
    for ii status {

    count += 1;
    let counter = count * 2;
    
    if count == 10 {
      break counter;
    }
}

3. 模式匹配 match

Rust 的match表达式是一种强大的模式匹配工具,允许你将一个值与多个模式进行比较,并根据匹配结果执行不同的代码。它类似于其他语言中的switchcase语句,但功能更加强大。

注意事项

  1. 穷尽性检查:Rust 强制要求match覆盖所有可能的值,否则会编译错误。

  2. 模式优先级:模式按顺序匹配,先定义的模式会优先处理。

  3. 所有权与借用:匹配可能转移所有权(如枚举变体),需注意生命周期。

适用场景

  • 处理枚举变体(如状态机)。

  • 解构复杂数据结构(结构体、元组)。

  • 条件分支与值绑定的组合。

基础语法

match表达式由一个表达式和多个分支组成,每个分支包含一个模式和对应的代码块。当表达式的值匹配某个模式时,执行该分支的代码。

match VALUE {
    PATTERN1 => EXPRESSION1,
    PATTERN2 => EXPRESSION2,
    PATTERN3 => EXPRESSION3,
    // ...
    _ => DEFAULT_EXPRESSION, // 通配符模式,处理剩余情况
}

1. 字面值匹配

直接匹配具体的值。

let number = 3;

match number {
    1 => println!("One"),
    2 => println!("Two"),
    3 => println!("Three"),
    _ => println!("Other"),
}

2. 变量绑定

匹配任意值并将其绑定到变量。

let some_value = Some(5);

match some_value {
    Some(x) => println!("Got a value: {}", x),
    None => println!("No value"),
}

3. 多重模式(OR)

使用|匹配多个值中的任意一个。

let x = 1;

match x {
    1 | 2 => println!("One or two"),
    3 => println!("Three"),
    _ => println!("Other"),
}

4. 范围匹配

使用..=匹配一个闭区间内的值。

let age = 25;

match age {
    0..=12 => println!("Child"),
    13..=19 => println!("Teenager"),
    20..=64 => println!("Adult"),
    _ => println!("Senior"),
}

5. 解构结构体

按字段解构结构体并绑定变量。

struct Point {
    x: i32,
    y: i32,
}

let p = Point { x: 0, y: 7 };

match p {
    Point { x, y: 0 } => println!("On the x-axis at {}", x),
    Point { x: 0, y } => println!("On the y-axis at {}", y),
    Point { x, y } => println!("At ({}, {})", x, y),
}

6. 解构枚举

处理枚举的不同变体。

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

let msg = Message::Move { x: 10, y: 20 };

match msg {
    Message::Quit => println!("Quit message"),
    Message::Move { x, y } => println!("Move to ({}, {})", x, y),
    Message::Write(text) => println!("Write: {}", text),
    Message::ChangeColor(r, g, b) => println!("Color: ({}, {}, {})", r, g, b),
}

7. 解构元组

按位置解构元组并绑定变量。

let tuple = (3, 4);

match tuple {
    (0, y) => println!("x is 0, y is {}", y),
    (x, 0) => println!("x is {}, y is 0", x),
    (x, y) => println!("x is {}, y is {}", x, y),
}

8. 守卫条件(if)

在模式后添加if条件,进一步筛选匹配。

let num = Some(4);

match num {
    Some(x) if x < 5 => println!("Less than five: {}", x),
    Some(x) => println!("Five or more: {}", x),
    None => println!("None"),
}

9. 绑定与忽略

使用_忽略不需要的部分,或使用..忽略剩余字段。

struct Point3D {
    x: i32,
    y: i32,
    z: i32,
}

let point = Point3D { x: 1, y: 2, z: 3 };

match point {
    Point3D { x, .. } => println!("x is {}", x), // 忽略 y 和 z
}

if letwhile let的对比

  • if let:当只关心一个模式匹配时,简化语法。

    let some_value = Some(3);
    
    if let Some(x) = some_value {
        println!("Got {}", x);
    }
    
  • while let:循环匹配,直到模式不匹配。

    let mut stack = vec![1, 2, 3];
    
    while let Some(top) = stack.pop() {
        println!("{}", top);
    }

高级用法

1. 引用匹配

匹配会将所有权转移,使用ref关键字匹配引用,避免所有权发生转移。

let s = String::from("hello");

match &s {
    ref r => println!("Got reference: {}", r),
}