mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-28 23:20:10 +08:00
[翻译完成][tech]: 20230507.0 ⭐️⭐️ Rust Basics Series 7 Using Loops in Rust
This commit is contained in:
parent
31597d96d0
commit
a3df515a81
@ -7,76 +7,78 @@
|
||||
[#]: publisher: " "
|
||||
[#]: url: " "
|
||||
|
||||
Rust Basics Series #7: Using Loops in Rust
|
||||
Rust 基础系列 #7: 在 Rust 中使用循环
|
||||
======
|
||||
|
||||
In the [previous article][1] of the Rust series, I went over the use of if and else keywords to handle the control flow of your Rust program.
|
||||
在 Rust 系列的 [上一篇文章][1] 中,我介绍了如何使用 if 和 else 关键字来处理 Rust 程序的控制流。
|
||||
|
||||
That is one way of handling the control flow of your program. The other way you can do this is by using loops. So let us look at loops in this follow-up article.
|
||||
这是处理程序控制流的一种方法。另一种方法是使用循环。因此,让我们在本文中看看循环。
|
||||
|
||||
### Loops available in Rust
|
||||
### Rust 中可用的循环
|
||||
|
||||
The Rust programming language has three different loops based on what you want to achieve and what is available:
|
||||
Rust 编程语言有三种不同的循环,基于你想要实现什么以及可用的内容:
|
||||
|
||||
- for
|
||||
- while
|
||||
- loop
|
||||
|
||||
I presume that you are familiar with `for` and `while` but `loop` might be new here. Let's start with familiar concepts first.
|
||||
我假设你对 `for` 和 `while` 已经很熟悉了,但 `loop` 对你来说可能是个新概念。让我们先从熟悉的概念开始。
|
||||
|
||||
### The for loop
|
||||
### for 循环
|
||||
|
||||
The `for` loop is primarily used to iterate over something called an iterator.
|
||||
`for` 循环主要用于迭代一种称为迭代器的东西。
|
||||
|
||||
This iterator can be made from anything, from an array, a vector (will be covered soon!), a range of values, or anything custom. The sky is the limit here.
|
||||
这个迭代器可以从任何东西中创建,从数组、向量(很快就会介绍!)、一系列值,或者任何自定义的东西。这里的可能性是无限的。
|
||||
|
||||
Let us look at the syntax of the `for` loop.
|
||||
来看看 `for` 循环的语法。
|
||||
|
||||
```
|
||||
for iterating_variable in iterator {
|
||||
<statement(s)>;
|
||||
for 迭代变量 in 迭代器 {
|
||||
<语句>;
|
||||
}
|
||||
```
|
||||
|
||||
The `iterating_variable` is more generally known as `i` in most other programming language tutorials ;)
|
||||
其中的 `迭代变量` 在大多数其他编程语言教程中通常被称为 `i` ;)
|
||||
|
||||
And an `iterator`, as I said, can be really anything that tells what the next value is, if any.
|
||||
`迭代器` 可以是任何东西,只要它能告诉下一个值是什么,如果有的话。
|
||||
|
||||
Let's understand this using a program.
|
||||
来通过一个程序来理解这个。
|
||||
|
||||
```
|
||||
fn main() {
|
||||
let my_arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
|
||||
println!("iteration over an array");
|
||||
println!("迭代数组");
|
||||
for element in my_arr {
|
||||
println!("{}", element);
|
||||
}
|
||||
|
||||
println!("\niteration over a real iterator");
|
||||
println!("\n迭代一个真正的迭代器");
|
||||
for element in my_arr.iter() {
|
||||
println!("{}", element);
|
||||
}
|
||||
|
||||
println!("\nPython-style range");
|
||||
println!("\nPython 风格的范围");
|
||||
for element in 0..10 {
|
||||
println!("{}", element);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here, I have declared an array that holds 10 numbers, from 0 to 9. On the `for` loop that is on line 5, I simply specify this array as the iterator and Rust automatically handles iteration over all the elements of this array for me. No fancy `my_arr[i]` magic is needed.
|
||||
这里,我声明了一个数组,它包含从 0 到 9 的 10 个数字。在第 5 行的 `for` 循环中,我只是将这个数组指定为迭代器,Rust 会自动处理对这个数组的所有元素的迭代。不需要花哨的 `my_arr[i]` 魔法。
|
||||
|
||||
But on line 10, I call the `.iter()` function on the array. This is an explicit mention of getting an iterator based on the values that `my_arr` consists of. The only difference between this loop and the loop on line 5 is that here you are being explicit by calling the `.iter()` function on the array.
|
||||
但是,在第 10 行,我调用了 `.iter()` 函数。这是一个明确的提及,它基于 `my_arr` 的值来获取一个迭代器。这个循环和第 5 行的循环之间唯一的区别是,这里你是通过在数组上调用 `.iter()` 函数来明确地调用它的。
|
||||
|
||||
Calling the `.iter()` function on a data type, _in this context,_ isn't strictly necessary. Since this is an array, which is a data type provided by the language itself, Rust already knows how to handle it. But you _will_ need it with custom data types.
|
||||
_在这个状况中_,在一个数据类型上调用 `.iter()` 函数不是必须的。因为这是一个数组,是语言本身提供的一种数据类型,Rust 已经知道如何处理它了。但是你 _需要_ 在自定义数据类型中使用它。
|
||||
|
||||
Finally, on line 15, we have a for loop that loops over a range. Well sort of. If you look closely, this range will look very similar to the Slice "type". Rust knows about this too and handles iteration _for_ you (haha, get it?).
|
||||
最后,在第 15 行,我们有一个循环,它循环遍历一个范围。嗯,差不多是这样。如果你仔细看,这个范围看起来很像 Slice “类型”。Rust 也知道这一点,并且 _为_ 你处理了迭代(哈哈,明白了吗?)。
|
||||
|
||||
The output looks like following:
|
||||
> LCTT 译注:此处的梗是,“为你处理了迭代” 的英文原文是 “handles iteration _for_ you",其中的 “for” 与 “for 循环” 的 “for” 是同一个单词。
|
||||
|
||||
输出如下:
|
||||
|
||||
```
|
||||
iteration over an array
|
||||
迭代数组
|
||||
0
|
||||
1
|
||||
2
|
||||
@ -88,7 +90,7 @@ iteration over an array
|
||||
8
|
||||
9
|
||||
|
||||
iteration over a real iterator
|
||||
迭代一个真正的迭代器
|
||||
0
|
||||
1
|
||||
2
|
||||
@ -100,7 +102,7 @@ iteration over a real iterator
|
||||
8
|
||||
9
|
||||
|
||||
Python-style range
|
||||
Python 风格的范围
|
||||
0
|
||||
1
|
||||
2
|
||||
@ -113,25 +115,25 @@ Python-style range
|
||||
9
|
||||
```
|
||||
|
||||
### The while loop
|
||||
### while 循环
|
||||
|
||||
The `while` loop can be thought to be very similar to an `if` conditional statement. With the `if` statement, provided that the user-provided condition evaluates to `true`, the code in the `if` statement's body is executed _once_.
|
||||
`while` 循环可以被认为是非常类似于 `if` 条件语句。使用 `if` 语句,只要用户提供的条件为 `true`,`if` 语句体中的代码就会被执行 _一次_。
|
||||
|
||||
But with the `while` loop, if the condition evaluates to `true`, the loop starts looping over the loop body. The loop will continue its iteration as long as the condition keeps on evaulating to `true`.
|
||||
但是,在 `while` 循环中,如果条件评估为 `true`,循环就会开始循环循环体。只要条件继续评估为 `true`,循环就会继续迭代。
|
||||
|
||||
The `while` loop stops only when the loop has completed the execution of all statements in the current iteration and upon checking the condition, it evaluates to `false`.
|
||||
`while` 循环只有在循环完成当前迭代中所有语句的执行并且在检查条件时,它的结果为 `false` 时才会停止。
|
||||
|
||||
Let's look at the syntax of a while loop...
|
||||
来看看 `while` 循环的语法...
|
||||
|
||||
```
|
||||
while condition {
|
||||
<statement(s)>;
|
||||
while 条件 {
|
||||
<语句>;
|
||||
}
|
||||
```
|
||||
|
||||
See? Very similar to an `if` conditional statement! No `else` blocks though ;)
|
||||
看到了吗?和 `if` 条件语句非常相似!不过没有 `else` 块 ;)
|
||||
|
||||
Let's look at a program to understand this better.
|
||||
来看一个程序来更好地理解这个。
|
||||
|
||||
```
|
||||
fn main() {
|
||||
@ -144,11 +146,11 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
I have a mutable variable, `var`, with an initial value of 0. The `while` loop will loop as long as the value stored in the mutable variable `var` is less than 3.
|
||||
我有一个可变变量 `var`,它的初始值为 0。只要可变变量 `var` 中存储的值小于 3,`while` 循环就会执行。
|
||||
|
||||
Inside the loop, `var`'s value gets printed and later on, its value gets incremented by 1.
|
||||
在循环中,`var` 的值被打印出来,然后它的值被增加 1。
|
||||
|
||||
Below is the output of the code written above:
|
||||
这是上面代码的输出:
|
||||
|
||||
```
|
||||
0
|
||||
@ -156,31 +158,25 @@ Below is the output of the code written above:
|
||||
2
|
||||
```
|
||||
|
||||
### The loop
|
||||
### loop 循环
|
||||
|
||||
Rust has an infinite loop. Yes, one with no condition for starting and no condition to stop. It just continues looping over and over again till infinity. But of course, has triggers to stop the loop execution from the code itself.
|
||||
Rust 有一个无限循环。是的,一个没有开始条件和停止条件的循环。它只是一直循环,直到永远。当然,它有触发器来停止代码本身的循环执行。
|
||||
|
||||
The syntax for this infinite loop is as follows:
|
||||
无限循环的语法如下:
|
||||
|
||||
```
|
||||
loop {
|
||||
<statement(s)>;
|
||||
<语句>;
|
||||
}
|
||||
```
|
||||
|
||||
📋
|
||||
> 📋 这些循环主要用于 GUI 软件,退出是一个 _显式_ 操作。
|
||||
|
||||
These loops are mostly used in GUI software where exiting is an
|
||||
在我给你一个例子之前,因为这个循环非常特殊,让我们先看看如何 _退出_ 它 :p
|
||||
|
||||
_explicit_
|
||||
要停止无限循环的执行,需要在循环内使用 `break` 关键字。
|
||||
|
||||
operation.
|
||||
|
||||
Before I even give you an example, since this loop is quite special, let's first look at how to _exit_ it :p
|
||||
|
||||
To stop the execution of an infinite loop, the `break` keyword is used inside the loop.
|
||||
|
||||
Let's look at an example where only whole numbers between 0 and 3 (inclusive) are printed to the program output.
|
||||
来看一个例子,只有 0 到 3 之间的整数(包括 0 和 3)才会被打印到程序输出。
|
||||
|
||||
```
|
||||
fn main() {
|
||||
@ -197,11 +193,11 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
The best way to interpret this particular example is to look at it as an unnecessarily expanded form of a `while` loop ;)
|
||||
看待这个特定的例子的最好方法是将它看作是一个增加了一堆没有必要的东西的 `while` 循环 ;)
|
||||
|
||||
You have a mutable variable `var` with an initial value of 0 that is used as an iterator, kind of. The infinite loop starts with an `if` condition that _should_`var`_'s value be greater than 3, the_`break` _keyword should be executed_ . Later on, like the previous example of the `while` loop, `var`'s value is printed to the stdout and then its value is incremented by 1.
|
||||
你有一个可变变量 `var`,它的初始值为 0,它被用作迭代器。无限循环从一个 `if` 条件开始,如果 `var` 的值大于 3,`break` 关键字就会被执行。后来,就像 `while` 循环的前一个例子一样,`var` 的值被打印到标准输出,然后它的值被增加 1。
|
||||
|
||||
It produces the following output:
|
||||
它的输出如下:
|
||||
|
||||
```
|
||||
0
|
||||
@ -210,43 +206,29 @@ It produces the following output:
|
||||
3
|
||||
```
|
||||
|
||||
### Labelled loops
|
||||
### 标记循环
|
||||
|
||||
Let's say there are two infinite loops, one nested in the other. For some reason, the exit condition is checked in the innermost loop but this exit condition is for exiting out of the outermost loop.
|
||||
假设有两个无限循环,一个嵌套在另一个中。由于某种原因,退出条件在最内层循环中被检查,但这个退出条件是为了退出最外层循环。
|
||||
|
||||
In such a case, labelling the loop(s) might be beneficial.
|
||||
在这种情况下,标记循环可能是有益的。
|
||||
|
||||
💡
|
||||
> 💡 `break` 和 `continue` 关键字并不仅仅用于无限循环。它们可以用于 Rust 语言提供的所有三种循环。
|
||||
|
||||
The use of labels
|
||||
接下来是如何标记循环。
|
||||
|
||||
```
|
||||
break
|
||||
'标记: loop {}
|
||||
```
|
||||
|
||||
and
|
||||
要告诉编译器一个循环被标记了,从一个单引号字符开始,输入它的标签,然后跟着一个冒号。然后,继续使用你通常定义循环的方式。
|
||||
|
||||
当你需要退出某个循环时,只需像这样指定循环标签:
|
||||
|
||||
```
|
||||
continue
|
||||
break '标记;
|
||||
```
|
||||
|
||||
keywords are not exclusive to the infinite loop. They can be used with all three loops that the Rust language offers.
|
||||
|
||||
Following is how to label a loop.
|
||||
|
||||
```
|
||||
'label: loop {}
|
||||
```
|
||||
|
||||
To tell the compiler that a loop is being labelled, start with a single quote character, type the label for it, and follow it with a colon. Then, continue with how you regularly define a loop.
|
||||
|
||||
When you need to break certain loop, simply specify the loop label like so:
|
||||
|
||||
```
|
||||
break 'label;
|
||||
```
|
||||
|
||||
Let's take a look at an example to better understand this.
|
||||
来看一个例子来更好地理解这个。
|
||||
|
||||
```
|
||||
fn main() {
|
||||
@ -269,13 +251,13 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
Here, I took two mutable variables `a` and `b` with the initial values set to 0 for both.
|
||||
这里,我使用两个可变变量 `a` 和 `b`,它们的初始值都设置为 0。
|
||||
|
||||
Later down, the outer-most loop is labelled `parent`. The 'parent' loop increments the value of varaible `a` by 1 and has an inner/child loop.
|
||||
然后,最外层的循环被标记为 `parent`。`parent` 循环将变量 `a` 的值增加 1,并有一个内部/子循环。
|
||||
|
||||
This child loop (on line 8) prints the values of variables `a` and `b`. Inside this loop, the value of `b` gets incremented by 1. And the exit condition is that `a + b == 10`. Meaning whenever the values stored in variables `a` and `b`, when added together, result in 10, the `parent` loop is broken. Even though the `break` condition on line 14 "belongs" to the inner loop, it breaks the `parent` loop.
|
||||
这个(在第 8 行的)子循环打印变量 `a` 和 `b` 的值。在这个循环内部,变量 `b` 的值增加了 1。退出条件是 `a + b == 10`。这意味着只要变量 `a` 和 `b` 中存储的值相加,结果为 10,`parent` 循环就会被打破。即使第 14 行的 `break` 条件“属于”内部循环,它也会打破 `parent` 循环。
|
||||
|
||||
Let's look at the program output now.
|
||||
来看看程序的输出。
|
||||
|
||||
```
|
||||
a: 1, b: 0
|
||||
@ -291,15 +273,15 @@ a: 1, b: 8
|
||||
1 + 9 = 10
|
||||
```
|
||||
|
||||
As evident from the program output, the loop stops as soon as `a` and `b` have the values 1 and 9 respectively.
|
||||
就像从程序输出中可以看出的那样,循环在 `a` 和 `b` 分别具有值 1 和 9 时停止。
|
||||
|
||||
### The continue keyword
|
||||
### continue 关键字
|
||||
|
||||
If you have already used loops in any other programming language like C/C++/Java/Python, you might already know the use of the `continue` keyword.
|
||||
如果你已经在其他编程语言(如 C/C++/Java/Python)中使用过循环,你可能已经知道 `continue` 关键字的用法。
|
||||
|
||||
While the `break` keyword is to stop the loop execution completely, the `continue` keyword is used to "skip" the **current iteration** of loop execution and start with the next iteration (if the conditions permit).
|
||||
当 `break` 关键字用于完全停止循环执行时,`continue` 关键字用于“跳过”循环执行的 **当前迭代** 并从下一迭代开始(如果条件允许)。
|
||||
|
||||
Let's look at an example to understand how the `continue` keyword works.
|
||||
来看一个例子来理解 `continue` 关键字的工作原理。
|
||||
|
||||
```
|
||||
fn main() {
|
||||
@ -312,11 +294,11 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
In the code above, I have a `for` loop that iterates over whole numbers between 0 and 9 (inclusive). As soon as the loop starts, I put a conditional check to see if the number is even or not. If the number is even, the `continue` keyword is executed.
|
||||
在上面的代码中,我有一个 `for` 循环,它迭代了 0 到 9 之间的整数(包括 0 和 9)。一旦循环开始,我就设置了一个条件检查,看看这个数字是不是偶数。如果这个数字是偶数,`continue` 关键字就会被执行。
|
||||
|
||||
But if the number is odd, the number gets printed to the program output.
|
||||
但是如果这个数字是奇数,这个数字就会被打印到程序输出。
|
||||
|
||||
Let's first look at the output of this program.
|
||||
来看看这个程序的输出。
|
||||
|
||||
```
|
||||
1
|
||||
@ -326,15 +308,15 @@ Let's first look at the output of this program.
|
||||
9
|
||||
```
|
||||
|
||||
As you can see, the loop appears to have been "going on" even though there clearly are even numbers between 0 and 9. But because I used the `continue` keyword, the loop execution stopped when that keyword was encountered.
|
||||
正如你所看到的,循环似乎一直在“进行”,尽管 0 到 9 之间显然有偶数。但是因为我使用了 `continue` 关键字,当遇到这个关键字时,循环执行就会停止。
|
||||
|
||||
The loop skipped whatever was under it and continued with the next iteration. That's why even numbers are not printed, but all odd numbers between 0 and 9 are printed to the proogram output.
|
||||
这个循环跳过了它下面的任何东西,并继续下一次迭代。这就是为什么偶数没有被打印出来,但是 0 到 9 之间的所有奇数都被打印到了程序输出中。
|
||||
|
||||
### Conclusion
|
||||
### 总结
|
||||
|
||||
To conclude this long article, I demonstrated the use of 3 different loops: `for`, `while` and `loop`. I also discussed two keywords that affect the control flow of these loops: `break` and `continue`.
|
||||
要总结这篇长文,我演示了 3 种不同循环的用法:`for`、`while` 和 `loop`。我还讨论了两个关键字,它们影响这些循环的控制流:`break` 和 `continue`。
|
||||
|
||||
I hope that you now understand the appropriate use case for each loop. Please let me know if you have any questions.
|
||||
我希望你现在能理解每个循环的适当用例。如果你有任何问题,请告诉我。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -349,4 +331,5 @@ via: https://itsfoss.com/rust-loops/
|
||||
|
||||
[a]: https://itsfoss.com/author/pratham/
|
||||
[b]: https://github.com/lkxed/
|
||||
[1]: https://itsfoss.com/rust-conditional-statements
|
||||
[1]: https://linux.cn/article-15896-1.html
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user