循环语句

循环语句用来重复执行一个代码块。

跟其他编程语言不同,Golang保持一种宁缺毋滥的态度,仅支持for语句循环,不支持while语句,后面我们会看到for语句完全能满足所有循环场景,因此也就不需要再多一种while循环语句了。

for循环语法

for循环语法如下:

for initialization; condition; post {

}

其中初始化语句initialization仅执行一次。初始化语句执行完之后判断condition条件,如果条件成立,则执行大括号中的循环体代码块,仅接着执行post语句。post语句执行完之后会再次判断condition是否成立,如果仍然成立,那么继续再执行循环体代码块。该过程会循环不停的执行下去,直到condition条件不再成立为止。

for语句中的三个组成部分initializationcondition以及post都是非必须的。下面我们通过例子来更好的理解Golang中的for循环。

例子

我们使用for循环来打印数字1到10。

package main

import "fmt"

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

Go Playground在线运行 这段程序中,变量i初始化为1。for循环的条件是判断i <= 10是否成立,如果成立,会打印出变量i的值,否则停止循环的执行,每次循环体执行后都是执行i++语句,将变量i加1,最终变量i会大于10,退出循环。

这段程序执行结果为:1 2 3 4 5 6 7 8 9 10for循环声明的变量i仅在for循环内部可见,无法在for循环外访问。

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")
}

Go Playground在线运行

这段代码中的循环体每次执行时都会检查变量i的值,如果该值大于5,就会通过break语句强制终止循环的执行。然后执行仅接着for循环的代码。这段代码输出如下:

1 2 3 4 5 
line after for loop

continue

continue语句用来跳过当前循环体的执行,循环体内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)
    }
}

Go Playground在线运行 这段程序中通过i % 2 == 0来判断i是否是偶数,如果条件成立,那么执行continue语句,因此会跳过后面的打印语句,进入下一次迭代。该程序输出如下:1 3 5 7 9

嵌套for循环

一个for循环可以嵌套在另一个for循环执行。 我们实现一个程序打印下面所示的图案:

*
**
***
****
*****

下面的程序使用嵌套循环来打印上述图案。

package main

import "fmt"

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

Go Playground在线运行 该程序中变量n表示行数。外层for循环中,变量i从0开始循环到4,共5次。内层for循环中,变量j从0开始循环到i。内层for循环每次执行打印符号*,外层for循环在每次内层for循环执行完之后打印一个换行,然后开始新的一行。

标签

我们知道,可以通过break语句来退出当前for循环,注意这里退出的是当前循环。那么如果想在内层for循环退出外出for循环怎么做到呢?Golang中我们可以通过标签来实现。

我们先看一下下面这个例子:

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

    }
}

Go 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的值相同时停止打印,即同时停止内、外层循环怎么实现呢?我们先尝试在内层循环增加break语句看下效果:

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
            }
        }

    }
}

Go Playground在线运行 跟我们想的一样,break仅能退出当前循环,无法退出双层循环,现在输出如下:

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

当然,如果可以在外层循环体也加个判断,然后使用break退出外层循环:

package main

import "fmt"

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

Go Playground在线运行 现在可以输出我们想要的结果了:

i = 0 , j = 1
i = 0 , j = 2
i = 0 , j = 3
i = 1 , 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
            }
        }

    }
}

Go Playground在线运行 这里我们给外层循环加了个标签outer,在内层循环体内,我们通过break outer指定要退出的循环标签名称,来直接了当的退出外层循环,输出如下:

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
    }
}

Go Playground在线运行 前面我们已经提到过,for语句中的三个组成部分initialization(循环变量初始化)、condition(条件判断)以及post(循环收尾语句)都是非必须的。这个例子中的for语句就不包含initialization(循环变量初始化)和post(循环收尾语句)。这里循环变量i的初始化在for循环外就完成了,而且循环变量i的递增是在循环体内执行的。该程序输出:0 2 4 6 8 10

上面程序中for语句中的分号;可以省略,写法如下:

package main

import "fmt"

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

Go Playground在线运行 细心就会发现,这不就是while循环的写法么?对!因此Golang中实现循环有for语句一种就够了。

我们可以在for语句中同时使用多个变量,比如下面的程序:

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

}

Go Playground在线运行 这里在for语句中同时初始化了两个变量noi,每次循环体执行结束后两个变量均加1。循环体执行的判断条件同时基于这两个变量来判断。该程序执行结果如下:

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

无限循环

创建无限循环的语句如下:

for {

}

下面的程序会无限打印Hello World

package main

import "fmt"

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

Golang中提供了一种非常方便的迭代数组的for循环方式,需要借助range,这个后面我们讲到数组时再详细讨论。

Last updated