目录
前言
条件分支:if
基本用法
if - else
if - else if - else
带初始化语句的 if
循环:for
完整 for 循环(类似 C 语言的 for)
省略初始化语句和后置语句(相当于 while)
无限循环
键值循环:for range
分支选择:switch
基本 switch
不带表达式的 switch(代替 if-else 链)
fallthrough 关键字
跳转:goto
循环控制:break 和 continue
break 示例
continue 示例
标签与 break/continue 配合
总结
前言
欢迎回到我们的Go语言学习系列!在前几篇文章中,我们学习了变量、常量、基本数据类型和运算符。有了这些基础,今天我们将进入一个更激动人心的主题——流程控制。
流程控制是编程语言的核心,它决定了程序的执行路径。通俗地说,就是让程序能够根据不同的条件做出不同的反应,或者重复执行某段代码。Go语言中的流程控制语句简洁而强大,主要包括:if、for、switch、goto,以及用于循环控制的break和continue。
让我们从最简单的开始。
条件分支:if
if语句用于根据布尔条件决定是否执行某段代码。Go 中的if不需要括号包裹条件(但括号也可以使用),并且必须写大括号{}。
Go语言中if条件判断的格式如下:
if 表达式1 { 分支1 } else if 表达式2 { 分支2 } else{ 分支3 }当表达式1的结果为true时,执行分支1,否则判断表达式2,如果满足则执行分支2,都不满足时,则执行分支3。 if判断中的else if和else都是可选的,可以根据实际需要进行选择。
注意:这里有一点特殊,Go语言规定与
if匹配的左括号{必须与if和表达式放在同一行,{放在其他位置会触发编译错误。 同理,与else匹配的{也必须与else写在同一行,else也必须与上一个if或else if右边的大括号在同一行。
其它语言中这样写可能是对的,但是在Go中,下列写法会触发编译错误,要小心:
if 表达式1 { 分支1 } else if 表达式2 { 分支2 } else{ 分支3 }基本用法
package main import "fmt" func main() { score := 85 if score >= 60 { fmt.Println("及格了!") } }if - else
if score >= 60 { fmt.Println("及格") } else { fmt.Println("不及格") }if - else if - else
if score >= 90 { fmt.Println("优秀") } else if score >= 75 { fmt.Println("良好") } else if score >= 60 { fmt.Println("及格") } else { fmt.Println("加油") }带初始化语句的 if
Go 允许在if条件之前执行一个简单的语句(通常是变量声明),该变量的作用域仅限于if-else块内部。
if age := 18; age >= 18 { fmt.Println("成年了") } else { fmt.Println("未成年") } // 这里无法使用 age,因为 age 只在 if-else 块内有效这种写法常用于获取可能出错的函数返回值,在 Go 标准库中非常常见。
循环:for
Go 语言没有while和do-while循环,只有一个for关键字,但它能实现所有循环场景。
完整 for 循环(类似 C 语言的 for)
for 初始化语句; 条件表达式; 后置语句 { // 循环体 }示例:打印 1 到 5
for i := 1; i <= 5; i++ { fmt.Println(i) }省略初始化语句和后置语句(相当于 while)
sum := 1 for sum < 1000 { sum += sum } fmt.Println(sum) // 1024无限循环
for { fmt.Println("无限循环,按 Ctrl+C 退出") }for循环可以通过break、goto、return、panic语句强制退出循环。
键值循环:for range
Go语言中可以使用for range遍历数组、切片、字符串、map 及通道(channel)。 通过for range遍历的返回值有以下规律:
- 数组、切片、字符串返回索引和值。
- map返回键和值。
- 通道(channel)只返回通道内的值。
Go1.22版本开始支持 for range 整数。
// 遍历切片 nums := []int{2, 4, 6} for index, value := range nums { fmt.Printf("索引: %d, 值: %d\n", index, value) } // 输出 // 索引: 0, 值: 2 // 索引: 1, 值: 4 // 索引: 2, 值: 6 // 只需要值,忽略索引 for _, value := range nums { fmt.Println(value) } // 输出 // 2 // 4 // 6 // 遍历字符串(得到 Unicode 码点) str := "Go语言" for i, ch := range str { fmt.Printf("%d %c\n", i, ch) } // 输出: // 0 G // 1 o // 2 语 // 3 言分支选择:switch
Go 的switch非常灵活,比 C/Java 的更强大。每个case默认带有break,不需要显式写break就能避免贯穿。而且case可以是任意类型(不限于整数),条件也可以是复杂表达式。
使用switch语句可方便地对大量的值进行条件判断。
基本 switch
func switchDemo1() { finger := 3 switch finger { case 1: fmt.Println("大拇指") case 2: fmt.Println("食指") case 3: fmt.Println("中指") case 4: fmt.Println("无名指") case 5: fmt.Println("小拇指") default: fmt.Println("无效的输入!") } }Go语言规定每个switch只能有一个default分支。
一个分支可以有多个值,多个case值中间使用英文逗号分隔。
day := "Saturday" switch day { case "Monday": fmt.Println("周一,加油") case "Tuesday", "Wednesday", "Thursday", "Friday": // 多个条件共享一个分支 fmt.Println("工作日") case "Saturday", "Sunday": fmt.Println("周末,放松一下") default: fmt.Println("未知") }不带表达式的 switch(代替 if-else 链)
分支还可以使用表达式,这时候switch语句后面不需要再跟判断变量。例如:
func switchDemo4() { age := 30 switch { case age < 25: fmt.Println("好好学习吧") case age > 25 && age < 35: fmt.Println("好好工作吧") case age > 60: fmt.Println("好好享受吧") default: fmt.Println("活着真好") } }fallthrough 关键字
Go 中默认不会贯穿到下一个case,但如果需要,可以使用fallthrough强制执行下一个case(不管其条件是否满足)。是为了兼容C语言中的case设计的。
switch num := 2; num { case 1: fmt.Println("1") case 2: fmt.Println("2") fallthrough case 3: fmt.Println("3") // 由于 fallthrough,这里也会执行 case 4: fmt.Println("4") }输出:
输出: 2 3跳转:goto
goto可以无条件跳转到同一函数内的标签。虽然goto名声不好(容易造成代码混乱),但在某些场景(如多层循环跳出、错误处理统一出口)中使用得当可以简化代码。Go 中保留了goto,但建议谨慎使用。
func main() { fmt.Println("start") if true { goto LABEL } fmt.Println("这行不会打印") LABEL: fmt.Println("end") }一个更实际的例子:跳出多层循环
func main() { for i := 0; i < 5; i++ { for j := 0; j < 5; j++ { if i == 2 && j == 2 { goto Out } fmt.Printf("i=%d, j=%d\n", i, j) } } Out: fmt.Println("跳出所有循环") }循环控制:break 和 continue
break 示例
break用于终止当前循环(最内层的for、switch或select)。
for i := 1; i <= 10; i++ { if i == 5 { break // 当 i 等于 5 时,跳出循环 } fmt.Print(i, " ") } // 输出: 1 2 3 4continue 示例
continue用于跳过本次循环的剩余代码,直接进入下一次循环。
for i := 1; i <= 5; i++ { if i%2 == 0 { continue // 偶数跳过,不打印 } fmt.Print(i, " ") } // 输出: 1 3 5标签与 break/continue 配合
Go 中的break和continue可以指定标签,从而跳出或继续到指定循环(不仅仅是当前最内层)。标签必须放在循环前面。
OuterLoop: for i := 1; i <= 3; i++ { for j := 1; j <= 3; j++ { if i == 2 && j == 2 { break OuterLoop // 跳出外层循环 } fmt.Printf("(%d,%d) ", i, j) } fmt.Println() } // 输出: // (1,1) (1,2) (1,3) // (2,1)同样,continue OuterLoop会直接跳到外层循环的下一次迭代。
OuterLoop: for i := 1; i <= 3; i++ { for j := 1; j <= 3; j++ { if i == 2 && j == 2 { cotinue OuterLoop // 跳到外层循环的下一次迭代 } fmt.Printf("(%d,%d) ", i, j) } fmt.Println() } // 输出 // (1,1) (1,2) (1,3) // (2,1) (3,1) (3,2) (3,3)总结
今天我们学习了 Go 语言中流程控制的全部核心内容:
if:条件分支,支持初始化语句。
for:唯一的循环关键字,可以模拟
while和无限循环,range用于遍历集合。switch:灵活的分支选择,每个
case自动 break,可使用fallthrough强制贯穿。goto:跳转到标签,谨慎使用。
break / continue:控制循环的跳出与跳过,可配合标签作用于外层循环。
这些语句组合在一起,可以构建出任何复杂的业务逻辑。掌握了它们,你已经可以写出丰富多彩的 Go 程序了。
下一篇文章,我们将深入讲解 Go 语言的数组,看看如何组织和复用代码。
感谢阅读,我们下篇再见!
如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!