Rust中if-else表达式的作用是实现条件分支。
它的语法和其他语言类似:
fn func(n : i32) -> bool {
if n < 0 {
print!("{} is negative", n);
} else if n > 0 {
print!("{} is positive", n);
} else {
print!("{} is zero", n);
}
true
}
在if语句中,后续的结果语句块要求一定要用大括号包起来,不能 省略,以便明确指出该if语句块的作用范围。这个规定是为了避免“悬空 else”导致的bug。比如下面这段C代码:
if (condition1)
if (condition2) {
}
else { //这个else分支是与第一个if相匹配的,还是与第二个if相匹配 的呢?从可读性上来说,答案是不够明显,容易出bug。但在C语言中与第二个if匹配,但自然感觉是与第一个if匹配
}
相反,条件表达式并未强制要求用小括号包起来;如果加上小括号,编译器反而会认为这是一个多余的小括号,给出警告。
💡 Rust 中的条件表达式必须是 bool 类型,例如下面的程序是错误的:
fn main() {
let number = 3;
if number { // Error!expected `bool`, found integerrustc(E0308)
println!("Yes");
}
}
虽然 C/C++ 语言中的条件表达式用整数表示,非 0 即真,但这个规则在很多注重代码安全性的语言中是被禁止的。
更重要的是,if-else结构还可以当表达式使用,比如:
let x : i32 = if condition { 1 } else { 10 };
如果使用if-else作为表达式,那么一定要注意,if分支和else分支的 类型必须一致,否则就不能构成一个合法的表达式,会出现编译错误。 如果else分支省略掉了,那么编译器会认为else分支的类型默认为()。 所以,下面这种写法一定会出现编译错误:
fn invalid_expr(cond: bool) -> i32 {
if cond {
42
} //若省略else,则else分支的类型默认为()
}
模式匹配
模式匹配是 rust 中重要,细节也比较多的一个部分,因为涉及到了 if 语句,这里简单提以下。
rust中没有switch语句,但match可以替换成switch,但match的功能比switch更强大:
let x = 5;
match x {
1 => println!("one"),
2 => println!("two"),
3 => println!("three"),
_ => println!("something else"),
}
上面的示例很好理解,分别匹配 1,2,3,否则就输出"something else"。
还有一种情况,
使用 if let 简化模式匹配
let s = Some('c');
// match 的方式匹配
match s {
Some(i) => println!("match {}",i),
_ => {},
}
// if let 的方式匹配
if let Some(i) = s{
println!("[if let] match {}",i);
}else {
println!("[if let] not match.");
}
在这个示例中,我们用 Some 包装了字符 "c",但只想匹配 "c" 字符时,用 match 的方式匹配比较繁琐。
使用 if let 语句可以简化模式匹配的代码,使代码更加清晰和简洁。
当然这段代码,现在看起来有些难以理解,比如 Some 包装后到底是什么,为什么变量 i 不需要声明赋值,if let 到底表示什么含义... 这些需要学习到后面的枚举模式才能理解,现在知道if 还可以配合let使用即可。