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 let 与 else 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 表达式:
- 是表达式,可以返回值
- 要求所有分支返回相同类型
- 条件必须是严格的布尔值
- 可以与模式匹配结合使用 (通过
if let) - 适合简单的条件逻辑 ,复杂模式匹配建议使用
match
通过合理使用 if 表达式,可以编写出既安全又表达力强的 Rust 代码。