Rust 条件语句(完整教程)

Rust 条件语句入门:从 if 到 match 的完整指南

在编程世界里,条件语句就像是道路的红绿灯——它决定程序的流向,让代码能够根据不同的情况做出不同的反应。无论是判断用户输入是否合法,还是根据状态选择执行路径,条件语句都是程序逻辑的核心。而 Rust 语言在设计上对条件语句的支持既强大又安全,它不仅语法简洁,还能在编译阶段就帮你发现潜在的逻辑错误。

今天我们就来深入聊聊 Rust 中的条件语句。无论你是刚接触编程的新人,还是有一定经验的开发者,这篇文章都会带你从基础到进阶,彻底掌握 Rust 条件语句的使用方式。我们不会讲太多理论,而是通过真实代码示例,一步步带你“写出来、跑起来、想明白”。


if 语句:最基础的判断逻辑

if 是所有编程语言中最常见的条件控制结构。在 Rust 中,它的语法和大多数语言类似,但有一个重要区别:条件表达式必须是布尔值(bool),不能是数字或字符串等类型。

fn main() {
    let age = 18;

    // 判断年龄是否达到法定成年标准
    if age >= 18 {
        println!("你已经成年,可以投票了!");
    } else {
        println!("你还未成年,需要等几年哦。");
    }
}

注释说明

  • age >= 18 是一个布尔表达式,结果为 true 或 false。
  • if 后面的花括号 {} 是代码块,只有条件为 true 时才会执行。
  • else 提供了条件不满足时的备选路径。
  • Rust 要求每个 if 块都必须有对应的 elseelse if,否则会报编译错误(除非你用 if let 等高级语法)。

多重判断:使用 else if

当需要判断多个条件时,可以使用 else if 来链式连接。

fn main() {
    let score = 85;

    if score >= 90 {
        println!("成绩优秀:A 等级");
    } else if score >= 80 {
        println!("成绩良好:B 等级");
    } else if score >= 70 {
        println!("成绩中等:C 等级");
    } else {
        println!("成绩不及格:需要努力了!");
    }
}

注释说明

  • 条件从上到下依次判断,一旦某个条件为 true,其余的就不再检查。
  • 这种写法很像“开关链条”:第一个开关打开,后面的就不用再按了。
  • 最后一个 else 是兜底逻辑,确保所有情况都被覆盖。

条件表达式:if 可以作为表达式返回值

这是 Rust 与其他语言的一个重要区别:if 是表达式,不是语句。这意味着它能返回一个值,可以赋给变量。

fn main() {
    let age = 20;
    let can_vote = if age >= 18 { true } else { false };

    println!("是否可以投票?{}", can_vote);
}

注释说明

  • if age >= 18 { true } else { false } 是一个完整的表达式,返回 bool 类型。
  • 整个 if 块的值被赋给了 can_vote 变量。
  • 这种写法比传统的 if-else 语句更简洁,尤其在需要根据条件选择返回值时非常有用。

实际应用:根据年龄返回角色描述

fn get_role(age: i32) -> &str {
    // if 语句返回字符串字面量
    if age >= 60 {
        "老年人"
    } else if age >= 18 {
        "成年人"
    } else if age >= 12 {
        "青少年"
    } else {
        "儿童"
    }
}

fn main() {
    let user_age = 25;
    println!("用户角色:{}", get_role(user_age));
}

注释说明

  • get_role 函数根据年龄返回不同的角色描述。
  • if 表达式的结果是 &str 类型,直接作为函数返回值。
  • 所有分支的返回类型必须一致,否则编译失败。

match 表达式:Rust 的“瑞士军刀”式条件

如果说 if 是一把小刀,那 match 就是瑞士军刀——功能强大、灵活多变。它不仅可以匹配数值,还能匹配枚举、结构体、模式等复杂结构。

基本语法:匹配单个值

fn main() {
    let day = 3;

    match day {
        1 => println!("星期一"),
        2 => println!("星期二"),
        3 => println!("星期三"),
        4 => println!("星期四"),
        5 => println!("星期五"),
        6 => println!("星期六"),
        7 => println!("星期日"),
        _ => println!("无效的天数"),
    }
}

注释说明

  • match 后面是待匹配的值(day)。
  • 每个 case=> 连接,左边是匹配模式,右边是执行代码。
  • _ 是通配符,匹配所有未明确列出的情况,相当于 else
  • match 是表达式,可以返回值。

模式匹配:处理多个值

fn main() {
    let weather = "sunny";

    match weather {
        "sunny" | "clear" => println!("今天天气晴朗,适合出门!"),
        "rainy" | "stormy" => println!("下雨了,记得带伞"),
        "cloudy" => println!("天阴,可能要下雨"),
        _ => println!("未知天气类型"),
    }
}

注释说明

  • | 是“或”操作符,表示匹配任意一个值。
  • sunnyclear 都会触发第一条逻辑。
  • 这种写法比写多个 if 更清晰,也更安全。

match 与枚举:强大的组合能力

Rust 的枚举(enum)与 match 配合使用,是处理状态机、协议解析等场景的利器。

// 定义一个表示 HTTP 状态码的枚举
enum HttpStatus {
    Ok,
    NotFound,
    InternalError,
    BadRequest,
}

fn handle_response(status: HttpStatus) {
    match status {
        HttpStatus::Ok => println!("请求成功,状态码 200"),
        HttpStatus::NotFound => println!("资源未找到,状态码 404"),
        HttpStatus::InternalError => println!("服务器内部错误,状态码 500"),
        HttpStatus::BadRequest => println!("请求格式错误,状态码 400"),
    }
}

fn main() {
    let response = HttpStatus::NotFound;
    handle_response(response);
}

注释说明

  • 枚举成员必须用 :: 显式调用。
  • match 能完整覆盖所有枚举成员,Rust 编译器会强制你处理所有可能情况。
  • 如果你漏掉某个成员,编译器会直接报错,避免运行时崩溃。

高级技巧:守卫(Guard)与模式绑定

match 支持更复杂的模式,比如“守卫”和“绑定”。

使用守卫(Guard)限制匹配条件

fn main() {
    let x = 10;

    match x {
        // 只有当 x > 5 时才匹配
        n if n < 10 => println!("x 是小于 10 的数字"),
        n if n > 10 => println!("x 是大于 10 的数字"),
        n => println!("x 正好是 10"),
    }
}

注释说明

  • if 后面的部分是“守卫”,用于进一步限制模式匹配。
  • n 是绑定变量,可以在守卫中使用。
  • 这种写法在处理复杂逻辑时非常有用。

模式绑定:提取结构体中的字段

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

fn main() {
    let p = Point { x: 3, y: 4 };

    match p {
        Point { x: 0, y: 0 } => println!("原点"),
        Point { x: 0, y: y_val } => println!("在 y 轴上,y = {}", y_val),
        Point { x: x_val, y: 0 } => println!("在 x 轴上,x = {}", x_val),
        Point { x: x_val, y: y_val } => println!("在第一象限,坐标是 ({}, {})", x_val, y_val),
    }
}

注释说明

  • x: 0 表示 x 字段必须等于 0。
  • y: y_val 表示将 y 的值绑定到变量 y_val
  • 这种写法可以避免重复调用 .x.y

Rust 条件语句的实用建议

在实际开发中,选择合适的条件结构很重要:

结构 适用场景 优势
if / else 简单布尔判断 语法直观,易于理解
if let 解构可选值(Option) 简洁,避免嵌套
match 多分支、枚举、复杂模式 完整覆盖,编译时安全
match with guard 需要额外条件判断 灵活控制匹配逻辑

小贴士:优先使用 match,因为它能强制你处理所有情况,减少遗漏风险。if 适合简单判断,但复杂场景下容易出错。


结语

Rust 条件语句不仅功能强大,更体现了 Rust “安全第一”的设计哲学。从基础的 if 到强大的 match,每一种结构都经过精心设计,帮助你在写代码时就避免常见的逻辑错误。

掌握这些语法,你不仅能写出更健壮的程序,还能深刻理解 Rust 的思维方式:让编译器帮你发现问题,而不是等到运行时才崩溃

现在,不妨动手试试,把这段代码运行起来,感受 Rust 条件语句的优雅与安全。当你第一次看到编译器提示“你漏掉了某个分支”时,你会明白:这,就是 Rust 的温柔。