【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 代码。

相关推荐
微小冷8 小时前
Rust异步编程详解
开发语言·rust·async·await·异步编程·tokio
鸿乃江边鸟8 小时前
Spark Datafusion Comet 向量化Rust Native--CometShuffleExchangeExec怎么控制读写
大数据·rust·spark·native
明飞19871 天前
tauri
rust
咚为1 天前
Rust tokio:Task ≠ Thread:Tokio 调度模型中的“假并发”与真实代价
开发语言·后端·rust
天天进步20151 天前
Motia性能进阶与未来:从现有源码推测 Rust 重构之路
开发语言·重构·rust
Hello.Reader2 天前
Rocket 0.5 响应体系Responder、流式输出、WebSocket 与 uri! 类型安全 URI
websocket·网络协议·安全·rust·rocket
FreeBuf_2 天前
黑客利用React Native CLI漏洞(CVE-2025-11953)在公开披露前部署Rust恶意软件
react native·react.js·rust
鸿乃江边鸟2 天前
Spark Datafusion Comet 向量化Rust Native--Native算子(CometNativeExec)怎么串联执行
大数据·rust·spark·native
mit6.8242 天前
[]try catch no | result yes
rust
Ivanqhz2 天前
向量化计算
开发语言·c++·后端·算法·支持向量机·rust