Golang 流程控制
一、条件语句
1. if-else 语句
(1)基本语法
if 布尔表达式1 {
// 布尔表达式1为真时执行
} else if 布尔表达式2 {
// 布尔表达式1为假、布尔表达式2为真时执行
} else {
// 所有布尔表达式都为假时执行
}
(2)注意事项
- Go 中的布尔表达式无需使用括号
() - 大括号
{}必须存在,即使只有一行语句 - 左括号
{必须与if或else在同一行 - 在
if之后、条件语句之前,可添加变量初始化语句,用分号;分隔,例如:if age := 20; age >= 18 { ... } - 不能用 0 或非 0 表示真假,必须显式使用布尔表达式
(3)示例
// 简单判断
var flag = true
if flag {
fmt.Println("true")
} else {
fmt.Println("false")
}
// 多条件判断
age := 17
if age >= 18 {
fmt.Println("adult")
} else if age >= 15 {
fmt.Println("not a adult")
} else {
fmt.Println("other")
}
// 带变量初始化的判断
if age2 := 20; age2 >= 18 {
fmt.Println("adult")
}
2. switch-case-default 语句
(1)基本语法
switch 变量 {
case 值1:
// 变量等于值1时执行
case 值2, 值3: // 支持多条件匹配
// 变量等于值2或值3时执行
default:
// 变量不匹配任何case时执行
}
(2)特殊关键字 fallthrough
- 用于实现 case 穿透,即执行当前 case 后继续执行下一个 case
- 若不使用 fallthrough,Go 的 switch 默认只执行匹配的一个 case(与 C++ 不同,无需显式 break)
(3)注意事项
- case 可以是表达式(此时 switch 后可省略变量)
- 可使用 break 终止当前 case 及后续执行(包括 fallthrough 后的语句)
(4)示例
// 多条件匹配
day := 3
switch day {
case 1, 2, 3, 4, 5:
fmt.Println("workday")
default:
fmt.Println("weekend")
}
// case 为表达式
score := 100
switch {
case score >= 100:
fmt.Println(">= 100")
fallthrough // 穿透到下一个case
case score >= 90 && score < 95:
fmt.Println(">= 90 && < 95")
default:
fmt.Println("other")
}
3. select-case-default 语句
(1)基本语法
select {
case 操作1: // 通常为通道操作
// 操作1可执行时执行
case 操作2:
// 操作2可执行时执行
default:
// 所有操作都不可执行时执行(可选)
}
(2)特点
- 类似 switch,但专门用于处理通道(channel)操作
- 随机执行一个可运行的 case;若没有可运行的 case 且无 default,则会阻塞,直到有 case 可运行
(3)示例
package main
import (
"fmt"
"time"
)
var chanInt = make(chan int)
var chanStr = make(chan string)
func main() {
go func() {
chanInt <- 100
chanStr <- "hello"
close(chanInt)
close(chanStr)
}()
for {
select {
case r := <-chanInt:
fmt.Printf("chanInt: %v\n", r)
case r := <-chanStr:
fmt.Printf("chanStr: %v\n", r)
default:
fmt.Printf("default...\n")
}
time.Sleep(time.Second)
}
}
二、循环语句
Go 语言中只有 for 循环,无 while、do-while 循环。
1. 普通 for 循环
(1)基本语法
// 完整形式:初始语句; 条件表达式; 结束语句
for i := 0; i < 10; i++ {
// 循环体
}
// 省略初始和结束语句(类似 while 循环)
i := 0
for i < 10 {
fmt.Printf("%v ", i)
i++
}
// 无限循环(类似 while(true))
for {
// 循环体(需内部用 break 终止)
}
2. for range 循环
(1)基本语法
for 索引/键, 值 := range 遍历对象 {
// 循环体
}
(2)适用场景及返回值
- 数组/切片:返回索引和对应值
- 字符串:返回索引和对应字符(rune 类型)
- map:返回键和对应值
- 通道(channel):只返回通道内的值
(3)示例
// 遍历数组
var arr = [5]int{1, 2, 3, 4, 5}
for i, v := range arr {
fmt.Printf("%v: %v, ", i, v)
}
// 遍历字符串
var str = "abc def"
for i, v := range str {
fmt.Printf("%d: %c, ", i, v)
}
// 遍历切片
var slice = []int{1, 2, 3, 4, 5}
for i, v := range slice {
fmt.Printf("%v: %v, ", i, v)
}
// 遍历 map
m := make(map[string]string)
m["name"] = "tom"
m["age"] = "20"
for k, v := range m {
fmt.Printf("%v: %v, ", k, v)
}
三、流程控制关键字
1. break
- 作用:结束当前 for、switch、select 的代码块
- 注意事项:
- 单独在 select 或无 fallthrough 的 switch 中,break 可有可无
- 在有 fallthrough 的 switch 中,break 可终止后续语句执行
- 带标签的 break 可跳出多层嵌套的代码块(如多层循环、switch 等)
// 带标签的 break 跳出多层循环
MY_LABEL:
for i := 0; i < 10; i++ {
if i == 5 {
break MY_LABEL // 直接跳出 MY_LABEL 标记的循环
}
fmt.Printf("%d ", i)
}
2. continue
- 作用:只能用于 for 循环,跳过当前循环的剩余部分,直接进入下一轮循环
- 支持带标签,跳过标签标记的循环的当前轮次
for i := 0; i < 5; i++ {
MY_LABEL:
for j := 0; j < 5; j++ {
if i == 2 && j == 3 {
continue MY_LABEL // 跳过当前 i=2、j=3 所在的内层循环轮次
}
fmt.Printf("%d-%d ", i, j)
}
fmt.Println()
}
3. goto
- 作用:跳转到代码中指定的标签位置(标签需单独一行,格式为
标签名:) - 注意:避免滥用,以免导致代码逻辑混乱
a := 1
if a == 1 {
goto LABEL1 // 跳转到 LABEL1
} else {
fmt.Println("not 1")
}
LABEL1:
fmt.Println("=1")