循环
Q7nl1s admin

循环语句用于重复执行一段代码。

for是 Go 中唯一可用的循环。Go 没有其他语言(如 C)中存在的 while 或 do while 循环。

for 循环语法

1
2
for initialisation; condition; post {  
}

初始化语句将只执行一次。循环初始化后,将检查条件。如果条件评估为真,则将执行内部循环的主体,{ }然后执行 post 语句。post 语句将在循环的每次成功迭代后执行。post语句执行后,条件会被重新检查。如果为真,循环将继续执行,否则 for 循环终止。

在 Go 中,initialisation, conditionpost这三个组件都是可选的。让我们看一个例子来更好地理解 for 循环。

Example

让我们编写一个程序,使用 for 循环打印从 1 到 10 的所有数字。

1
2
3
4
5
6
7
8
9
10
11
package main

import (
"fmt"
)

func main() {
for i := 1; i <= 10; i++ {
fmt.Printf(" %d",i)
}
}

在上面的程序中,i被初始化为 1。条件语句将检查 if i <= 10。如果条件为真,则打印 i 的值,否则终止循环。post 语句在每次迭代结束时将 i 递增 1。一旦i大于 10,循环终止。

上面的程序将打印1 2 3 4 5 6 7 8 9 10

在 for 循环中声明的变量仅在循环范围内可用。因此i不能在 for 循环体之外访问。

break

break语句用于在 for 循环完成正常执行之前突然终止 for 循环,并将控件移动到 for 循环之后的代码行。

让我们编写一个程序,使用 break 打印从 1 到 5 的数字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import (
"fmt"
)

func main() {
for i := 1; i <= 10; i++ {
if i > 5 {
break //loop is terminated if i > 5
}
fmt.Printf("%d ", i)
}
fmt.Printf("\nline after for loop")
}

在上面的程序中,每次迭代都会检查 i 的值。如果 i 大于 5 则break执行并终止循环。然后执行 for 循环之后的 print 语句。上面的程序会输出,

1
2
1 2 3 4 5  
line after for loop

continue

continue语句用于跳过 for 循环的当前迭代。在 continue 语句之后出现在 for 循环中的所有代码都不会在当前迭代中执行。循环将继续进行下一次迭代。

让我们编写一个程序,使用 continue 打印从 1 到 10 的所有奇数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main

import (
"fmt"
)

func main() {
for i := 1; i <= 10; i++ {
if i%2 == 0 {
continue
}
fmt.Printf("%d ", i)
}
}

在上面的程序中,该行if i%2 == 0检查 i 除以 2 的余数是否为 0。如果为零,则数字为偶数,continue执行语句,控制移至循环的下一次迭代。因此,将不会调用 continue 之后的 print 语句,并且循环继续进行下一次迭代。上述程序的输出是1 3 5 7 9

嵌套for循环

for循环内部有另一个for循环的循环称为嵌套 for 循环。

让我们通过编写一个打印以下序列的程序来理解嵌套的 for 循环。

1
2
3
4
5
*
**
***
****
*****

下面的程序使用嵌套的 for 循环来打印序列。第8行中的变量n存储序列中的行数。在我们的例子中,它是5。 外部 for 循环i0迭代到4,内部 for 循环j0迭代到当前i的值。内部循环为每次迭代打印*,外部循环在每次迭代结束时打印一个新行。运行这个程序,你会看到输出的序列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import (
"fmt"
)

func main() {
n := 5
for i := 0; i < n; i++ {
for j := 0; j <= i; j++ {
fmt.Print("*")
}
fmt.Println()
}
}

Labels

标签可用于从内部 for 循环中断外部 for 循环。让我们通过一个简单的例子来理解我的意思。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main

import (
"fmt"
)

func main() {
for i := 0; i < 3; i++ {
for j := 1; j < 4; j++ {
fmt.Printf("i = %d , j = %d\n", i, j)
}

}
}

上面的程序是不言自明的,它将打印

1
2
3
4
5
6
7
8
9
i = 0 , j = 1  
i = 0 , j = 2
i = 0 , j = 3
i = 1 , j = 1
i = 1 , j = 2
i = 1 , j = 3
i = 2 , j = 1
i = 2 , j = 2
i = 2 , j = 3

这没什么特别的:)

如果我们想在ij相等时停止打印怎么办。为此,我们需要从外部for循环跳出。当ij相等时在内循环中添加一个break只会从内循环中断。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main

import (
"fmt"
)

func main() {
for i := 0; i < 3; i++ {
for j := 1; j < 4; j++ {
fmt.Printf("i = %d , j = %d\n", i, j)
if i == j {
break
}
}

}
}

在上面的程序中,我在内部for循环中添加了一个break 在第10行中当ij相等的时候。这break只会跳出内部for循环,外部循环会继续。该程序将打印。

1
2
3
4
5
6
i = 0 , j = 1  
i = 0 , j = 2
i = 0 , j = 3
i = 1 , j = 1
i = 2 , j = 1
i = 2 , j = 2

这不是预期的输出。我们需要在ij相等的时候停止打印,当它们等于1时。

这就是标签来拯救我们的地方。标签可用于中断外循环。让我们用标签重写上面的程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main

import (
"fmt"
)

func main() {
outer:
for i := 0; i < 3; i++ {
for j := 1; j < 4; j++ {
fmt.Printf("i = %d , j = %d\n", i, j)
if i == j {
break outer
}
}

}
}
1
2
3
4
i = 0 , j = 1  
i = 0 , j = 2
i = 0 , j = 3
i = 1 , j = 1

More examples

让我们编写更多代码来涵盖for循环的所有变体。

下面的程序打印从 0 到 10 的所有偶数。

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import (
"fmt"
)

func main() {
i := 0
for ;i <= 10; { // initialisation and post are omitted
fmt.Printf("%d ", i)
i += 2
}
}

正如我们已经知道的 for 循环的所有三个组成部分,即initialisation, conditionpost都是可选的。在上面的程序中,initialisationpost被省略了。i在for 循环之外被初始化为0。条件为i <= 10. i 在 for 循环中每次增加 2。上述程序输出0 2 4 6 8 10

上述程序的for循环中的分号也可以省略。这种格式可以被认为是 while 循环的替代方案。上面的程序可以重写为:

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import (
"fmt"
)

func main() {
i := 0
for i <= 10 { //semicolons are ommitted and only condition is present
fmt.Printf("%d ", i)
i += 2
}
}

可以在 for 循环中声明和操作多个变量。让我们编写一个程序,使用多个变量声明打印以下序列。

1
2
3
4
5
6
7
8
9
10
10 * 1 = 10  
11 * 2 = 22
12 * 3 = 36
13 * 4 = 52
14 * 5 = 70
15 * 6 = 90
16 * 7 = 112
17 * 8 = 136
18 * 9 = 162
19 * 10 = 190
1
2
3
4
5
6
7
8
9
10
11
12
package main

import (
"fmt"
)

func main() {
for no, i := 10, 1; i <= 10 && no <= 19; i, no = i+1, no+1 { //multiple initialisation and increment
fmt.Printf("%d * %d = %d\n", no, i, no*i)
}

}

在上述程序中noi分别被声明和初始化为 10 和 1。它们在每次迭代结束时递增 1。在条件中使用布尔运算符&&来确保i小于或等于 10 并且no也小于或等于 19。

无限循环

创建无限循环的语法是:

1
2
for {  
}

以下程序将继续打印Hello World而不会终止。

1
2
3
4
5
6
7
8
9
package main

import "fmt"

func main() {
for {
fmt.Println("Hello World")
}
}

如果你尝试在go playground中运行上述程序,您将收到错误“处理时间太长”。请尝试在你的本地系统中运行它以无限打印“Hello World”。

还有一个构造范围是可以在for循环中用于数组操作。当我们学习数组时,我们将介绍这一点。

 Comments
Comment plugin failed to load
Loading comment plugin
Powered by Hexo & Theme Keep
Unique Visitor Page View