3.5 控制流:if else
3.5.0. 写在正文之前
欢迎来到Rust自学的第三章,一共有6个小节,分别是:
通过第二章的小游戏(没看的初学者强烈建议看一下),相信你已经学会了基本的Rust语法,而在第三章我们将更深一层,了解Rust中的通用的编程概念。
3.5.1. if表达式的基本认识
if表达式允许根据条件执行不同的代码分支。- 这个条件必须是布尔类型。这点不同于Ruby、JS和C++,它们会把
if后的非布尔值转换为布尔值。 - 条件可以是一个字面值、一个表达式或是一个变量。
- 这个条件必须是布尔类型。这点不同于Ruby、JS和C++,它们会把
- 在
if表达式中,与条件相关联的代码就叫做分支(在讲match时就有提到过这个概念)。 - 可选地,在后面可以加上一个
else表达式。
fn main(){
let machine = 6657;
if machine < 114514 {
println!("condition is true");
} else {
println!("condition is false");
}
}
在这个例子中,machine的值小于114514,所以程序会执行println!("condition is true");这一行。如果修改machine的值使其不再小于114514,那么程序就会执行else后的代码块。
3.5.2. 用else if处理多重条件
如果需要进行多重条件判断又不想在else下不停地写嵌套,那么使用else if就是很好的选项。
fn main(){
let number = 6;
if number % 4 == 0 {
println!("Number is divisible by 4");
} else if number % 3 == 0 {
println!("Number is divisible by 3");
} else if number % 2 == 0 {
println!("Number is divisible by 2");
} else {
println!("Number is not divisible by 4, 3, or 2");
}
}
由于6既能被3整除也能被2整除,所以else if number % 3 == 0和else if number % 2 == 0都是true。因为if、else if和else是按从上到下的顺序判断的,所以谁先出现就执行谁。在这个例子中,else if number % 3 == 0在前面,所以程序就会执行println!("Number is divisible by 3");,而else if number % 2 == 0下的代码块就不会被执行。
如果程序中使用了多于一个else if,通常最好使用match来重构代码。
比如上面那段代码就可以重构为(非唯一解):
fn main() {
let number = 6;
match number {
n if n % 4 == 0 => println!("Number is divisible by 4"),
n if n % 3 == 0 => println!("Number is divisible by 3"),
n if n % 2 == 0 => println!("Number is divisible by 2"),
_ => println!("Number is not divisible by 4, 3, or 2"),
}
}
显而易见,使用match的代码更加直观。
3.5.3. 在let语句中使用if
if在Rust中是一个表达式,所以可以将它放在let语句中等号的右边。
fn main(){
let condition = true;
let number = if condition { 5 } else { 6 };
println!("The value of number is: {}", number);
}
在这个例子中,因为condition是true,所以会把5赋给number,最后的输出结果就是The value of number is: 5。如果condition是false,那么就会把else后的值6赋给number。
这种写法与Python非常相像,但是两者有本质上的区别:
-
Rust:
- 在Rust中,
if-else是表达式,可以直接返回值。换句话说,if结构本身可以参与到其他表达式的计算中。 - 在Rust中,几乎任何代码块都可以是表达式,因此
{}块也可以返回一个值。
- 在Rust中,
-
Python:
- 在Python中,
if-else是一种特定的类三元形式,专门为单行条件表达式设计。 - Python的普通
if-else语句是控制流的一部分,它不返回值,也不能嵌入到其他表达式中。
- 在Python中,
fn main(){
let condition = true;
let number = if condition { 5 } else { "6" };
println!("The value of number is: {}", number);
}
Output:
error[E0308]: `if` and `else` have incompatible types
--> src/main.rs:3:41
|
3 | let number = if condition { 5 } else { "6" };
| - ^^^ expected integer, found `&str`
| |
| expected because of this
意思是if和else返回了不兼容的类型。因为Rust是静态类型、强类型语言,在编译时就必须知道变量的类型,以便这个变量在其他地方使用。在这个例子中,if分支的返回值是i32,而else分支的返回值是字符串类型。编译器无法在编译时确定number的类型到底是i32还是字符串,所以会报错。
一句话总结:if-else 表达式的分支必须返回相同类型的值。