第九篇 Loops 循环
欢迎来到Golang教程系列的第九篇
循环语句(loop)是用来重复执行一个代码块的。
for是Go中唯一的循环变量,Go没有那些在C语言中出现的while或do while循环。
for循环语法
for initialosation; condition; post {
}
初始化语句只会执行一次,循环初始化之后,condition条件语句就会检查,如果condition条件判断为true,那就开始执行post语句,然后循环体{}里面的代码块接着执行。post语句会在每一次成功循环迭代后执行,post语句执行完成之后,condition语句会再次检查条件,如果为true,循环继续,不然的话,就终止循环。
所有三个部分就是初始化部分、条件判断部分,还有Post部分都是可选的。让我们看下面一个例子以便更好理解。
例子
我们写一个程序用来循环打印数字1到10.
package main
import (
"fmt"
)
func main() {
for i := 1; i <= 10; i++ {
fmt.Printf(" %d",i)
}
}
上面的程序中,i初始化为1,条件语句检查判断i <= 10,如果条件为true,就会打印i的值,否则就终止循环。在每次迭代之后,post语句会让i的值加1,一旦i的值大于10,那么就会终止循环。
上面的程序输出 1 2 3 4 5 6 7 8 9 10
在循环语句中声明的变量它的有效范围只在循环之内,因此,不可在循环体之外调用i。
break
break语句是在for循环正常结束之前,用来突然终止程序的,它会把当前控制移动到for循环的结尾。
让我们用break写一个打印1到5的数字的程序。
package main
import (
"fmt"
)
func main() {
for i := 1; i <= 10; i++ {
if i > 5 {
break // 终止循环
}
fmt.Printf(" %d",i)
}
fmt.Printf("\nline after for loop")
}
在上面的程序中,在每次迭代中,都会检查i的值,如果i的值大于5,那么就会执行break终止循环。在循环之后的打印语句就会执行。上面的程序将会输出
1 2 3 4 5
line after for loo
continue
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,那么i
为偶数,然后执行continue语句。当前控制跳到循环的下一个迭代。因此,continue后面的print语句不会执行,然后继续下一个迭代。上面的程序有输出: 1 3 5 7 9
嵌套循环
在一个for循环里面还有另外一个for循环,我们叫这为嵌套循环。
为更好地了解嵌套循环,让我们写一个顺序输出下面字符的程序。
*
**
***
****
*****
下面的程序用for循环打印序列,其中,n := 5中变量n保存了序列的行数。在我们的例子中是n为5,外层的循环迭代i是从0到4,内部循环j是从0到当前i的值。内循环每次迭代打印一个*,而外循环每次迭代打印新的一行。运行下面的程序,你就可看到序列输出。
package main
import (
"fmt"
)
func main() {
n := 5
for i := 1; i <= n; i++ {
for j := 0; j < i; j++ {
fmt.Print("*")
}
fmt.Println()
}
}
labels 标记
labels 可以用来在内部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)
}
}
}
上面程序的输出
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相等时,我们想要停止打印。要实现这个,我们需要break外层的for循环。但是当i等于j时,在内层for循环新增一个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
}
}
}
}
在上面的程序中,当i等于j时,我在内层for循环新增了一个break,这个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
这并不是我们预期的输出,我们需要在i和j都为1的时候停止打印。
labels能帮我们解决这个问题, labels可以用来break外层的for循环。下面让我们写一个关于怎么用labels的程序。
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
}
}
}
}
在上面的程序中,我们在外层for循环新增了一个labelouter,并且通过指定break outerlabels跳出外层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; { // 省略了初始化和post部分
fmt.Printf("%d ", i)
i += 2
}
}
我们知道for循环有三个部分,初始化部分、条件部分,post部分都是可选的。在上面的程序中,初始化和post部分省略了,i在for循环之外初始化。循环只要执行i <= 10,i在循环体内每次都加2.上面的程序输出0 2 4 6 8 10
上面程序中的分号(semicolons)也是可以省略的。这个是可以考虑用来代替while循环。上面的程序可以重写成下面
package main
import (
"fmt"
)
func main() {
i := 0
for i <= 10 { // 分号都被省略了,只出现条件语句
fmt.Printf("%d ", i)
i += 2
}
}
可以在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 {
fmt.Printf("%d * %d = %d\n", no, i, no*i)
}
}
在上面的程序中,no和i分别声明并初始化为10和1,在每次循环中都增加1.布尔操作符&&是用来条件判断i小于或等于10,且no是小于或等于19.
无限循环
下面是创建一个无限循环的语法。
for {
}
下面的程序将会连续不断的打印Hello World。
package main
import "fmt"
func main() {
for {
fmt.Println("Hello World")
}
}
如果你尝试执行上面的程序,你就会看到错误process took too long,你可以立即在你的机器上执行这个程序输出Hello World。
还有一个构造范围可用于for循环中进行数组操作。我们将在学习数组的时候讨论这个问题
以上就是本篇的全部,感谢阅读,这是我第一次翻译,难免会有翻译不当的地方,如果有什么反馈和评论,欢迎提出来!
浙公网安备 33010602011771号