[譯] part 9: golang 迴圈語句

咔嘰咔嘰發表於2019-04-21

迴圈語句被用來重複執行一塊程式碼。

for是 Go 中唯一的迴圈語句。 Go 沒有whiledo while迴圈,這些迴圈存在於其他如 C 語言中。

for 迴圈的語法

for initialisation; condition; post {  
}
複製程式碼

初始化語句只執行一次。初始化迴圈後,將檢查條件。如果條件的計算結果為true,則執行{}內的迴圈體,然後執行post語句。post語句將在每次成功迭代迴圈後執行。執行post語句後,將重新檢查條件。如果是true,則迴圈將繼續執行,否則for迴圈終止。

在 Go 中,這三個元件叫初始化,conditionpost都是可選的。讓我們看一個例子來更好地理解 for 迴圈。

例子

我們編寫一個程式,使用 for 迴圈列印從 1 到 10 的所有數字。

package main

import (  
    "fmt"
)

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

Run in playground

在上面的程式中,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")
}
複製程式碼

Run in playground

在上述程式中,每次迭代都檢查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)
    }
}
複製程式碼

Run in playground

在上面的程式中,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()
    }
}
複製程式碼

Run in playground

標籤 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)
        }

    }
}
複製程式碼

Run in playground

理解上面的程式碼不難,上述程式將列印,

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相等時,在內部 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
            }
        }

    }
}
複製程式碼

Run in playground

在上面的程式中,當ij相等時,我在內部 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  
複製程式碼

這不是期望的輸出。當ij相等時,即當它們都等於 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
            }
        }

    }
}
複製程式碼

Run in plaground

在上面的程式中,我們在第 8 行為外部 for 迴圈新增了一個標籤。我們通過中斷指定標籤來結束外部 for 迴圈。當ij相等時,該程式將停止列印。該程式將輸出

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
    }
}
複製程式碼

Run in playground

我們已經知道 for 迴圈有三個元件,即initialisationconditionpost是可選的。在上面的程式中,省略了initialisationpost。我在 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
    }
}
複製程式碼

Run in playground

我們也可以在 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)
    }

}
複製程式碼

Run in playground

在上面的程式中,noi被宣告並初始化為 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 迴圈以進行陣列的迭代操作。我們瞭解陣列時,再介紹這一點。

相關文章