Golang语言流程控制之for循环结构篇
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一. for循环
1 for循环基本写法
Go语言中的所有循环类型均可以使用for关键字来完成,换句话说,Go语言并不支持"while","do...while"类似的写法。
for循环的基本格式如下:
for 初始表达式;布尔表达式;迭代因子{
循环体语句
}
for循环语句是支持迭代的一种通用结构,是最有效,最灵活的循环结构。
for循环在第一次反复之前要进行初始化,即初始化表达式,随后,对布尔表达式进行判定,若判定结果为true,则执行循环体,否则,终止循环;随后在某一次反复的时候,进行某种形式的"步进",即执行迭代因子。
- 1.初始表达式设置循环变量的初值;
- 2.条件判断部分为任意布尔表达式;
- 3.迭代因子控制循环变量的增减;
for循环在执行条件判定后,先执行的循环体部分,再执行步进。
无限循环(也称为"死循环")基本格式如下:
for {
循环体语句
}
for循环可以通过break、goto、return、panic语句强制退出循环。
Go语言中可以使用for range遍历数组、切片、字符串、map及通道(channel),其返回值有以下规律:
(1)数组、切片、字符串返回索引和值。
(2)map返回键和值。
(3)通道(channel)只返回通道内的值。
温馨提示:
- 1.for循环的初始化表达式,不能用var定义变量的形式,要用":=";
- 2.for循环作用就是让程序员写代码的效率提高了(说白了,只是让程序员写代码简洁而已),但是底层该怎么执行还是怎么执行的,底层效率没有任何提高;
2 for循环引入
package main
import "fmt"
func main() {
// 实现一个功能,求和: 1,3,5,7,9
// 实现方式一: 变量定义太多啦!
var (
a int = 1
b = 3
c = 5
d = 7
e = 9
sum1 = 0
)
sum1 += a
sum1 += b
sum1 += c
sum1 += d
sum1 += e
fmt.Printf("sum1 = %d\n", sum1)
// 实现方式二: 重复代码过多
var (
i int = 1
sum2 = 0
)
sum2 += i
i += 2
sum2 += i
i += 2
sum2 += i
i += 2
sum2 += i
i += 2
sum2 += i
fmt.Printf("sum2 = %d\n", sum2)
// 实现方式三: 利用for循环解决问题
var sum3 int = 0
for x := 1; x <= 9; x += 2 {
sum3 += x
}
fmt.Printf("sum3 = %d\n", sum3)
/*
温馨提示:
- 1.for循环的初始化表达式,不能用var定义变量的形式,要用":=";
- 2.for循环作用就是让程序员写代码的效率提高了(说白了,只是让程序员写代码简洁而已),但是底层该怎么执行还是怎么执行的,底层效率没有任何提高;
*/
// for循环的变种写法,for循环语法非常灵活。
var (
sum4 int = 0
y = 1 // 变量的初始化
)
for y <= 9 { // 条件表达式,判断条件
sum4 += y // 循环体
y += 2 // 迭代因子
}
fmt.Printf("sum4 = %d\n", sum4)
// x变量无法访问,但是y变量可以被访问。
// fmt.Printf("x = %d\n", x)
fmt.Printf("y = %d\n", y)
}
3.for循环原理
如上图所示,是for循环的执行顺序图解。
在经历5次循环之后,该进行第6次循环时i的值变为11,然后11不满足i<=9的条件,返回结果为false,因此不再执行循环体的代码,因此最终sum3的结果为25。
4.for死循环案例
package main
import (
"fmt"
"time"
)
func main() {
var count int64 = 0
// 死循环
for {
time.Sleep(1 * time.Second) // 每次睡眠1秒钟,用于模拟打游戏的时间!
count++
fmt.Printf("第【%d】次复活\n", count)
if count == 3 {
fmt.Println("闯关失败,即将重新开始闯关!")
count = 0
}
}
}
二 .for range键值循环案例
1 for range概述
for range结构是GO语言特有的一种迭代结构,在许多情况下都非常有用。
for range可以遍历数组,切片,字符串,map及channel。for range语法上类似于其他语言中的foreach语句。
2 for range遍历字符串
package main
import (
"fmt"
)
func main() {
// 暂时先不要用中文测试,因为对于方式一的遍历有影响,对于方式二的没有影响
// teacher := "JasonYin2020"
teacher := "JasonYin2020尹正杰"
// 方式一: 普通for循环,按照字节进行遍历输出的,如果想要使用这种方式遍历汉字,等学完切片再处理不迟。
// for index := 0; index < len(teacher); index++ {
// fmt.Printf("第【%d】个字符是: %c\n", index+1, teacher[index])
// }
// 方式二: 对teacher进行遍历,遍历的每个结果的索引值被k接受,每个结果的具体数值被v接受。
for k, v := range teacher {
fmt.Printf("第【%d】个字符是: %c\n", k, v)
}
}
三.break关键字
1.break作用
- 1.switch分支中,每个case分支后都有break结束当前分支,但是在Go语言中break可以省略不写;;
- 2.break可以结束正在执行的for循环;
- 3.break的作用结束离他最近的循环;
2 break跳出循环
package main
import (
"fmt"
)
func main() {
var (
age uint8
myAge uint8 = 29
)
for {
fmt.Print("请猜测我的年龄,输入数字即可:>>> ")
fmt.Scanln(&age)
if age < myAge {
fmt.Println("猜小了...")
} else if age > myAge {
fmt.Println("猜大了...")
} else {
fmt.Printf("恭喜您,猜对啦,我的年龄是: %d,你是一个好人!\n", myAge)
// break可以结束正在执行的for循环
break
}
}
fmt.Println("猜年龄程序运行结束,欢迎下次使用~")
}
3.break退出嵌套for循环
package main
import "fmt"
func main() {
for i := 1; i <= 3; i++ {
for j := 7; j <= 9; j++ {
fmt.Printf("i: %d, j:%d \n", i, j)
if i == 2 && j == 8 {
// 此处break的作用就是结束离它最近的for循环。
break
}
}
}
fmt.Println("程序运行结束啦......")
}
4 break退出指定的标签
package main
import "fmt"
func main() {
/*
温馨提示:
1.一旦定义标签,则必须在后续的代码中引用标签,否则就会抛出异常: label <LABEL_NAME> defined and not used
2.本案例的"haha"标签其实是可以不定义的,因为break默认就是退出最近一层的for循环哟;此处我故意这样写你为了加深大家的理解;
*/
xixi: // 定义一个名为"xixi"的标签
for i := 1; i <= 5; i++ {
haha: // 定义一个名为"haha"的标签
for j := 7; j <= 9; j++ {
fmt.Printf("i: %d, j:%d \n", i, j)
if i == 1 && j == 8 {
// 结束指定标签对应的循环
break haha
}
if i == 3 && j == 8 {
// 结束指定标签对应的循环
break xixi
}
}
}
fmt.Println("程序运行结束啦......")
}
四.continue关键字
1 continue作用
- 1.结束本次循环,继续下一次循环;
- 2.
2 continue结束本次循环
package main
import (
"fmt"
)
func main() {
var (
number int = 0
)
fmt.Print("请输入一个范围以便于显示7的倍数:>>> ")
fmt.Scanln(&number)
for i := 0; i < number; i++ {
if i%7 != 0 {
// 结束本次循环,继续下一次循环
continue
} else {
fmt.Printf("【%d】是7的倍数\n", i)
}
}
fmt.Println("数7游戏运行结束啦......")
}
3 continue结束嵌套for循环
package main
import "fmt"
func main() {
for i := 1; i <= 3; i++ {
for j := 7; j <= 9; j++ {
if i == 2 && j == 8 {
// 此处continue的作用就是结束本次离它最近的for循环,然后继续下一次离它最近的for循环
continue
}
fmt.Printf("i: %d, j:%d \n", i, j)
}
}
fmt.Println("程序运行结束啦......")
}
4 continue结束指定的标签
package main
import "fmt"
func main() {
/*
温馨提示:
1.一旦定义标签,则必须在后续的代码中引用标签,否则就会抛出异常: label <LABEL_NAME> defined and not used
2.本案例的"haha"标签其实是可以不定义的,因为continue默认就是跳出最近一层的for循环哟;此处我故意这样写你为了加深大家的理解;
*/
xixi: // 定义一个名为"xixi"的标签
for i := 1; i <= 5; i++ {
haha: // 定义一个名为"haha"的标签
for j := 7; j <= 9; j++ {
if i == 1 && j == 8 {
// 结束指定标签对应的循环
continue haha
}
if i == 3 && j == 8 {
// 结束指定标签对应的循环
continue xixi
}
fmt.Printf("i: %d, j:%d \n", i, j)
}
}
fmt.Println("程序运行结束啦......")
}
五.goto关键字
1 goto概述
Golang中的goto语句通过标签进行代码间的无条件跳转。
goto语句通常与条件语句配合使用,可用来实现条件转移,goto语句可以在快速跳出循环、避免重复退出上有一定的帮助。
Go语言中使用goto语句能简化一些代码的实现过程。
温馨提示:
1.goto在汇编语言使用较多,在高级语言中使用较少;
2.在Go程序设计中一般不建议使用goto语句,以免造成程序流程的混乱。
2 goto测试样例
package main
import "fmt"
func main() {
var (
a int = 10
b = 5
)
fmt.Println("hello golang1")
fmt.Println("hello golang2")
if a > b {
// goto一般配合条件结构一起使用,跳转到指定标签
goto xixi
}
fmt.Println("hello golang3")
fmt.Println("hello golang4")
fmt.Println("hello golang5")
fmt.Println("hello golang6")
fmt.Println("hello golang7")
xixi:
fmt.Println("hello golang8")
fmt.Println("hello golang9")
}
3 goto跳转到指定标签
package main
import (
"fmt"
)
func main() {
// 在不使用goto指令时,定义一个标志位,用来判断是否结束外层嵌套for循环。
flag := false
for i := 1; i < 5; i++ {
for j := 7; j < 9; j++ {
if i == 2 && j == 8 {
flag = true
break
}
fmt.Printf("%d -- %d \n", i, j)
}
// 通过标志位来判断是否跳出外层for循环
if flag {
break
}
}
fmt.Printf("通过标志位[flag = %t]退出,嵌套for循环结束啦....\n", flag)
for i := 1; i < 5; i++ {
for j := 7; j < 9; j++ {
if i == 2 && j == 8 {
goto haha
}
fmt.Printf("%d -- %d \n", i, j)
}
}
// 定义一个标签名为"haha"(该名称可以自定义哟),标签需要被引用否则会报错
// 实际工作中,尽量少用goto指令,尽管它看上去比上面使用flag的方式语法更简洁,但用的多容易混乱哟!
haha:
fmt.Println("程序运行结束,嵌套for循环结束啦....")
}
六.return关键字
1 return概述
return用于直接结束当前函数,不在继续往后执行代码。
2 return测试样例
package main
import "fmt"
func main() {
for i := 1; i <= 100; i++ {
fmt.Printf("当前是第[%d]次循环\n", i)
if i == 5 {
// 直接结束当前函数,不在继续往后执行代码
return
}
}
// 由于上面已经return了,因此本行代码是不会被执行的哟~
fmt.Println("程序运行结束")
}
七.练习题
1.计算100以内的偶数的和
package main
import (
"fmt"
)
func main() {
// 计算100以内的偶数的和
for number := 0; number <= 100; number++ {
if number%2 == 0 {
fmt.Printf("【%d】是偶数\n", number)
}
}
}
2.统计300-500以内的所有素数
package main
import (
"fmt"
)
func main() {
// 素数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数
// 统计素数的个数
var count int = 0
for i := 300; i < 500; i++ {
// 定义标志位,如果找到了素数,则为true,默认我们就认为本次循环找到了素数
flag := true
// 判断i是否为素数
for j := 2; j < i; j++ {
if i%j == 0 {
flag = false
break
}
}
// 打印素数
if flag {
count++
// fmt.Printf("%d是素数\n", i)
}
}
fmt.Printf("300-500以内,共计有[%d]个素数!", count)
}
3.编写代码打印99乘法表
package main
import (
"fmt"
)
func main() {
for i := 1; i <= 9; i++ {
for j := 1; j <= i; j++ {
fmt.Printf("%d x %d = %d\t", j, i, i*j)
}
fmt.Println()
}
}
当你的才华还撑不起你的野心的时候,你就应该静下心来学习。当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练。问问自己,想要怎样的人生。
欢迎交流学习技术交流,个人微信: "JasonYin2020"(添加时请备注来源及意图备注)
作者: 尹正杰, 博客: https://www.cnblogs.com/yinzhengjie/p/18293060