- 原文地址:Part 9: Loops
- 原文作者:Naveen R
- 譯者:咔嘰咔嘰 轉載請註明出處。
迴圈語句被用來重複執行一塊程式碼。
for
是 Go 中唯一的迴圈語句。 Go 沒有while
或do while
迴圈,這些迴圈存在於其他如 C 語言中。
for 迴圈的語法
for initialisation; condition; post {
}
複製程式碼
初始化語句只執行一次。初始化迴圈後,將檢查條件。如果條件的計算結果為true
,則執行{}
內的迴圈體,然後執行post
語句。post
語句將在每次成功迭代迴圈後執行。執行post
語句後,將重新檢查條件。如果是true
,則迴圈將繼續執行,否則for
迴圈終止。
在 Go 中,這三個元件叫初始化,condition
和post
都是可選的。讓我們看一個例子來更好地理解 for 迴圈。
例子
我們編寫一個程式,使用 for 迴圈列印從 1 到 10 的所有數字。
package main
import (
"fmt"
)
func main() {
for i := 1; i <= 10; i++ {
fmt.Printf(" %d",i)
}
}
複製程式碼
在上面的程式中,i
被初始化為 1。條件語句將檢查i <= 10
。如果條件為滿足,則列印i
的值,否則迴圈終止,post
語句在每次迭代結束時將i
遞增 1。一旦大於 10,迴圈終止。
程式將輸出,1 2 3 4 5 6 7 8 9 10
在 for 迴圈中宣告的變數僅在迴圈範圍內可用。因此我不能在程式碼塊外獲取i
。
break
break 語句用於在正常執行之前終止 for 迴圈,並執行 for 迴圈之後的程式碼行。
讓我們編寫一個程式,使用 break 並列印 1 到 5 的數字。
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 3 4 5
line after for loop
複製程式碼
cotinue
continue 語句用於跳過當前 for 迴圈的迭代。在 continue 語句之後的程式碼都不會在當前迭代中執行。迴圈將繼續下一次迭代。
讓我們編寫一個程式,使用 continue 來列印從 1 到 10 的所有奇數。
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。如果為 0 則為偶數並執行continue
語句,執行下一次迭代環。因此,不會呼叫continue
之後的print
語句,迴圈進入下一次迭代。上述程式的輸出為1 3 5 7 9
巢狀 for 迴圈
在迴圈中包含另一個 for 迴圈的 for 迴圈稱為巢狀 for 迴圈。
讓我們通過編寫一個列印下面序列的程式來理解巢狀 for 迴圈。
*
**
***
****
*****
複製程式碼
下面的程式使用巢狀 for 迴圈來列印序列。變數 n 儲存序列的行數,在我們的例子中n
是 5。外部 for 迴圈從 0 到 4 迭代i
,內部 for 迴圈將 j 從 0 迭代到i
的當前值。內部迴圈迭代列印*,外部迴圈在每次迭代結束時換行。執行此程式,將看到上述列印的序列。
package main
import (
"fmt"
)
func main() {
n := 5
for i := 0; i < n; i++ {
for j := 0; j <= i; j++ {
fmt.Print("*")
}
fmt.Println()
}
}
複製程式碼
標籤 label
標籤可用於從內部 for 迴圈內部打破外部迴圈。讓我們通過一個簡單的例子來理解我的意思。(譯者注:Go 語言中可以用到 label 的有 goto,break,continue)
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)
}
}
}
複製程式碼
理解上面的程式碼不難,上述程式將列印,
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
複製程式碼
如果我們想在i
和j
相等時停止列印怎麼辦?要做到這一點,我們需要在外部 for 迴圈中斷。當i
和j
相等時,在內部 for 迴圈中新增一個 break 只會從內部 for 迴圈中中斷。
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
}
}
}
}
複製程式碼
在上面的程式中,當i
和j
相等時,我在內部 for 迴圈中新增了一個 break。這將僅從內部 for 迴圈中斷,外迴圈將繼續,該程式將列印,
i = 0 , j = 1
i = 0 , j = 2
i = 0 , j = 3
i = 1 , j = 1
i = 2 , j = 1
i = 2 , j = 2
複製程式碼
這不是期望的輸出。當i
和j
相等時,即當它們都等於 1 時,我們需要停止列印。
這是標籤發揮作用的地方。標籤可用於從外迴圈中斷開。讓我們用標籤重寫上面的程式。
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
}
}
}
}
複製程式碼
在上面的程式中,我們在第 8 行為外部 for 迴圈新增了一個標籤。我們通過中斷指定標籤來結束外部 for 迴圈。當i
和j
相等時,該程式將停止列印。該程式將輸出
i = 0 , j = 1
i = 0 , j = 2
i = 0 , j = 3
i = 1 , j = 1
複製程式碼
更多例子
讓我們編寫一些程式碼來熟悉 for 迴圈的各種用法。
下面的程式列印從 0 到 10 的所有偶數。
package main
import (
"fmt"
)
func main() {
i := 0
for ;i <= 10; { // initialisation and post are omitted
fmt.Printf("%d ", i)
i += 2
}
}
複製程式碼
我們已經知道 for 迴圈有三個元件,即initialisation
,condition
和post
是可選的。在上面的程式中,省略了initialisation
和post
。我在 for 迴圈之外初始化i
為 0。只要i <= 10
,就會執行迴圈。i
在 for 迴圈中增加 2。上述程式輸出0 2 4 6 8 10
。
也可以省略上述程式的 for 迴圈中的分號。這種格式可以被認為是 while 迴圈的替代方案。上述程式可以改寫為,
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 迴圈中宣告和操作多個變數。來編寫一個程式,在 for 語句中使用多個變數宣告並列印下面的序列。
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
複製程式碼
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)
}
}
複製程式碼
在上面的程式中,no
和i
被宣告並初始化為 10 和 1。它們在每次迭代結束時遞增 1。在condition
中使用布林運算子&&
以確保i
小於或等於 10 並且no
小於或等於 19。
無限迴圈
無限迴圈的語法為,
for {
}
複製程式碼
以下程式將一直列印 Hello World 且不會結束。
package main
import "fmt"
func main() {
for {
fmt.Println("Hello World")
}
}
複製程式碼
如果你在 playground 上執行該程式,將會報錯process took too long
。請嘗試在本地系統中執行它以無限地列印Hello World
。
還有range
可以用 for 迴圈以進行陣列的迭代操作。我們瞭解陣列時,再介紹這一點。