摘要
在编程当中,通常都需要对一些条件进行判断,并根据条件为真与否选择执行对应代码。这些代码可能执行一次,或者在条件满足的条件下循环执行,知道条件不再成立。
因此,代码逻辑中条件控制主要分两类,分支和循环。
表达条件分支的一般有if
及其关联的分支等。Rust还支持一种更为强大的分支处理方式match
。我们将在其他文章中专门了解。
控制循环的语句有loop
,while
,for
。
控制流
if
if
表达式用于在给定条件为真时执行某些代码。
let num1 = 5;
let num2 = 10;
if num < num2 {
println!("{} is smaller than {}.", num1, num2);
}
在Rust中,用于条件判断的值或者表达式必须是bool
类型,在一些编程语言中,如C/C++,一切非零的表达式都能够隐式转换为true
。但这在Rust中是不允许的。
if
常结合else
, else if
使用,用于处理多种不同条件。
let num1 = 5;
let num2 = 10;
if num < num2 {
println!("{} is smaller than {}.", num1, num2);
} else if num1 == num2 {
println!("{} equal to {}",num1, num2);
} else {
println!("{} is bigger than {}", num1, num2);
}
正如在Rust基础 - 函数一文中,所涉及到的有关if
的内容,它是表达式可以返回值,因此if
语句还可以用于根据条件初始化值。
let num1 = 5;
let num2 = 10;
let big_num = if num1 >= num2 {
num1
} else {
num2
};
if
用于初始化值时,就变成了语句的一部分,语句末尾需要分号结尾。因此不要忘了给这条赋值语句加上分号。
if
表达式必须结合else
以及可能的else if
分支处理所有可能的分支情况。如下面一种情况,只处理了部分分支,编译时就会报错:
let num1 = 5;
let num2 = 10;
let num = if num1 < num2 {
num1
}; // 错误,只处理了 num1 < num2 的分支情况。
if
表达式中各个分支返回的类型也必须一致。不能再不同分支中返回不同类型的值:
let num1 = 5;
let num2 = 10;
let num = if num1 < num2 {
num1
} else {
"num2"
}; // 错误,两个分支返回了不同类型的值
loop
loop
用于重复执行一段代码。
loop {
println!("Hello!");
}
loop
表达式需要在其表达式体内判断条件跳出循环。跳出循环的方法是使用break
语句:
let mut count = 0;
loop {
count += 1;
if count >= 100 {
break;
}
}
break
语句可以携带值,使loop
作为表达式返回值:
let mut count = 0;
let ret_count = loop {
count += 3;
if count >= 100 {
break 100;
}
};
break
可以在任何循环体中使用,但是携带返回值时,只能在loop
循环语句中使用。
for
Rust中for
循环体用于遍历一个序列。
let arr = [1,2,3,4];
for ele in arr.iter() {
println!("{}",ele);
}
查看上面的代码,我们可以发现对数组arr
进行遍历时调用了方法iter()
,这是因为实际上for
循环是在实现了std::iter::Iterator
特性的对象上进行操作的。
let arr = [1,2,3,4];
for ele in arr {
println!("{}",ele);
}
如果去掉该方法,我们可以看到错误的原因:
error[E0277]: `[{integer}; 4]` is not an iterator
--> src\main.rs:29:16
|
29 | for num in arr {
| ^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
|
= help: the trait `std::iter::Iterator` is not implemented for `[{integer}; 4]`
= note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
= note: required by `std::iter::IntoIterator::into_iter`
上面的提示说明了数组没有实现std::iter::Iterator
特性,但是它可以通过调用iter()
返回一个实现了该特性的对象,或者通过引用&
获得一个数组切片,因为切片实现了该特性。