【Rust】if表达式详解

Rust 的 if 表达式是条件执行的基础结构,与其他语言中的 if 语句类似,但在 Rust 中它不仅是语句,更是表达式,这意味着它可以返回值。

基础语法

基本的 if 语句

rust 复制代码
fn main() {
    let number = 7;

    if number < 5 {
        println!("条件为真");
    } else {
        println!("条件为假");
    }
}

if 作为表达式

这是 Rust if 最强大的特性之一:它可以返回值,因此可以用于赋值。

rust 复制代码
fn main() {
    let condition = true;
    
    // if 作为表达式使用,返回一个值
    let number = if condition {
        5  // 注意:这里没有分号
    } else {
        6  // 两个分支必须返回相同类型
    };
    
    println!("number 的值为: {}", number); // 输出: number 的值为: 5
}

多条件分支

else if

rust 复制代码
fn main() {
    let number = 6;

    if number % 4 == 0 {
        println!("能被4整除");
    } else if number % 3 == 0 {
        println!("能被3整除");
    } else if number % 2 == 0 {
        println!("能被2整除");
    } else {
        println!("不能被2、3、4整除");
    }
}

返回值的多分支

rust 复制代码
fn main() {
    let score = 85;
    
    let grade = if score >= 90 {
        'A'
    } else if score >= 80 {
        'B'
    } else if score >= 70 {
        'C'
    } else if score >= 60 {
        'D'
    } else {
        'F'
    };
    
    println!("分数 {} 对应的等级是: {}", score, grade);
}

if 表达式的关键特性

1. 必须返回相同类型

rust 复制代码
fn main() {
    let condition = true;
    
    // 正确:两个分支都返回 i32
    let x = if condition { 5 } else { 6 };
    
    // 错误:类型不匹配
    // let y = if condition { 5 } else { "six" }; // 编译错误
    
    // 可以使用相同的枚举类型
    #[derive(Debug)]
    enum Result {
        Number(i32),
        Text(String),
    }
    
    let result = if condition {
        Result::Number(5)
    } else {
        Result::Text("six".to_string())
    };
    println!("{:?}", result);
}

2. 块表达式返回值

rust 复制代码
fn main() {
    let x = 10;
    
    let result = if x > 5 {
        let y = x * 2;
        y + 1  // 这是块的最后表达式,作为返回值
    } else {
        x
    };
    
    println!("结果是: {}", result); // 输出: 结果是: 21
}

与模式匹配结合

if 条件中使用模式匹配

rust 复制代码
fn main() {
    let some_value = Some(5);
    
    // 传统写法
    if let Some(x) = some_value {
        println!("值是: {}", x);
    }
    
    // 结合 else
    let maybe_number: Option<i32> = None;
    
    if let Some(x) = maybe_number {
        println!("值是: {}", x);
    } else {
        println!("没有值");
    }
}

if letelse if

rust 复制代码
fn main() {
    enum Message {
        Quit,
        Move { x: i32, y: i32 },
        Write(String),
    }
    
    let msg = Message::Move { x: 10, y: 20 };
    
    if let Message::Quit = msg {
        println!("退出消息");
    } else if let Message::Move { x, y } = msg {
        println!("移动到 ({}, {})", x, y);
    } else if let Message::Write(text) = msg {
        println!("写入: {}", text);
    }
}

条件必须是布尔值

Rust 不像其他语言那样自动转换类型为布尔值:

rust 复制代码
fn main() {
    let number = 5;
    
    // 正确:使用比较操作
    if number != 0 {
        println!("数字不是零");
    }
    
    // 错误:Rust 不会自动将数字转换为布尔值
    // if number {  // 编译错误
    //     println!("这不会编译");
    // }
    
    // 正确使用方式
    if number > 0 {
        println!("正数");
    }
}

嵌套 if 表达式

rust 复制代码
fn main() {
    let a = 10;
    let b = 20;
    
    let max = if a > b {
        a
    } else {
        if a == b {
            a  // 也可以是 b,两者相等
        } else {
            b
        }
    };
    
    println!("最大值是: {}", max);
    
    // 更简洁的写法
    let max2 = if a > b { a } else if a == b { a } else { b };
    println!("最大值是: {}", max2);
}

实战示例

1. 配置处理

rust 复制代码
struct Config {
    debug: bool,
    log_level: u8,
}

impl Config {
    fn log_level_name(&self) -> &'static str {
        if self.debug {
            "DEBUG"
        } else if self.log_level >= 3 {
            "INFO"
        } else if self.log_level >= 1 {
            "WARN"
        } else {
            "ERROR"
        }
    }
}

fn main() {
    let config = Config { debug: true, log_level: 2 };
    println!("日志级别: {}", config.log_level_name());
}

2. 数据验证

rust 复制代码
fn validate_age(age: u8) -> Result<String, String> {
    let message = if age < 13 {
        "儿童".to_string()
    } else if age < 20 {
        "青少年".to_string()
    } else if age < 65 {
        "成年人".to_string()
    } else {
        "老年人".to_string()
    };
    
    Ok(message)
}

fn main() {
    match validate_age(25) {
        Ok(msg) => println!("年龄分类: {}", msg),
        Err(e) => println!("错误: {}", e),
    }
}

3. 复杂条件逻辑

rust 复制代码
fn calculate_discount(price: f64, is_member: bool, coupon_code: Option<&str>) -> f64 {
    let base_discount = if is_member { 0.1 } else { 0.0 };
    
    let extra_discount = if let Some(code) = coupon_code {
        if code == "SAVE20" {
            0.2
        } else if code == "SAVE10" {
            0.1
        } else {
            0.05
        }
    } else {
        0.0
    };
    
    let total_discount = if base_discount + extra_discount > 0.3 {
        0.3  // 最大折扣30%
    } else {
        base_discount + extra_discount
    };
    
    price * (1.0 - total_discount)
}

fn main() {
    let final_price = calculate_discount(100.0, true, Some("SAVE20"));
    println!("最终价格: {:.2}", final_price); // 70.00
}

match 的比较

特性 if 表达式 match 表达式
返回值 ✅ 是表达式 ✅ 是表达式
模式匹配 有限(通过 if let ✅ 完整支持
穷尽性检查 ❌ 不检查 ✅ 强制检查
多分支 else if 多个 => 分支
适用场景 简单条件判断 复杂模式匹配

何时使用 if vs match

rust 复制代码
fn example(value: Option<i32>) {
    // 简单条件判断 - 适合用 if
    if let Some(x) = value {
        println!("有值: {}", x);
    }
    
    // 多条件判断 - 适合用 if
    let x = 5;
    if x > 0 && x < 10 {
        println!("个位数");
    }
    
    // 复杂模式匹配 - 适合用 match
    match value {
        Some(0) => println!("零"),
        Some(1..=9) => println!("个位数"),
        Some(10..=99) => println!("两位数"),
        Some(_) => println!("大数"),
        None => println!("无"),
    }
}

常见陷阱和最佳实践

1. 避免过深的嵌套

rust 复制代码
// 不好:嵌套太深
fn bad_example(x: i32, y: i32, z: i32) -> i32 {
    if x > 0 {
        if y > 0 {
            if z > 0 {
                x + y + z
            } else {
                x + y
            }
        } else {
            x
        }
    } else {
        0
    }
}

// 更好:使用早期返回或 match
fn good_example(x: i32, y: i32, z: i32) -> i32 {
    if x <= 0 { return 0; }
    if y <= 0 { return x; }
    if z <= 0 { return x + y; }
    x + y + z
}

2. 使用布尔表达式简化

rust 复制代码
fn main() {
    let a = true;
    let b = false;
    
    // 冗长写法
    let result1 = if a {
        if b {
            "both"
        } else {
            "a only"
        }
    } else {
        if b {
            "b only"
        } else {
            "none"
        }
    };
    
    // 简洁写法
    let result2 = match (a, b) {
        (true, true) => "both",
        (true, false) => "a only",
        (false, true) => "b only",
        (false, false) => "none",
    };
    
    println!("{} {}", result1, result2);
}

3. 利用 if 表达式的特性

rust 复制代码
fn process_data(data: &[i32]) -> String {
    // 在条件中计算结果
    let sum: i32 = data.iter().sum();
    
    // 使用 if 表达式进行复杂的逻辑
    let category = if data.is_empty() {
        "空数据".to_string()
    } else {
        let avg = sum as f64 / data.len() as f64;
        if avg > 100.0 {
            format!("高平均值: {:.2}", avg)
        } else if avg > 50.0 {
            format!("中平均值: {:.2}", avg)
        } else {
            format!("低平均值: {:.2}", avg)
        }
    };
    
    category
}

fn main() {
    let data = vec![30, 40, 50];
    println!("{}", process_data(&data));
}

总结

Rust 的 if 表达式:

  1. 是表达式,可以返回值
  2. 要求所有分支返回相同类型
  3. 条件必须是严格的布尔值
  4. 可以与模式匹配结合使用 (通过 if let
  5. 适合简单的条件逻辑 ,复杂模式匹配建议使用 match

通过合理使用 if 表达式,可以编写出既安全又表达力强的 Rust 代码。

相关推荐
盛者无名6 小时前
Rust的所有权(Owenership)
开发语言·rust
BlockChain8886 小时前
MPC 钱包实战(三):Rust MPC Node + Java 调度层 + ETH 实际转账(可运行)
java·开发语言·rust
分布式存储与RustFS20 小时前
RustFS在AI场景下的实测:从GPU到存储的完整加速方案
开发语言·人工智能·rust·对象存储·企业存储·rustfs·minio国产化替代
柠檬丶抒情1 天前
Rust no_std 裸机移植:9 条避坑与实战手册
开发语言·mongodb·rust
FAFU_kyp1 天前
Rust 流程控制学习教程
学习·算法·rust
FAFU_kyp1 天前
Rust 模式匹配:match 与 if let 详解
开发语言·后端·rust
Mr -老鬼2 天前
Java VS Rust
java·开发语言·rust
张心独酌2 天前
Rust开发案例库-静态服务器
服务器·开发语言·rust
liuxuzxx2 天前
使用Rust构建MCP Server Stdio类型
rust·mcp
FAFU_kyp2 天前
Rust 结构体(struct)
开发语言·后端·rust