1. 条件分支 if - else
Go 的 if 语句不需要括号。特色之处在于支持在条件判断前执行一段初始化语句,该语句声明的变量作用域仅限于 if-else 块内。
package main
import "fmt"
func main() {
// 标准 if-else
score := 85
if score >= 90 {
fmt.Println("优秀")
} else if score >= 60 {
fmt.Println("及格")
} else {
fmt.Println("不及格")
}
// 带初始化语句的 if(num 仅在 if/else 内部有效)
if num := 10; num%2 == 0 {
fmt.Println(num, "是偶数")
}
}
2. 多路选择 switch
Go 的 switch 比传统 C/Java 更强大、更安全:
- 自动 break:默认匹配到一个
case执行完后就自动退出,不需要手动写break。 - 支持表达式:
switch后面可以不跟变量,直接在case中写布尔条件表达式。 - 类型断言:可用于判断接口变量的具体类型 (
type switch)。 fallthrough关键字:如果需要强制贯穿执行下一个case,可以显式加上fallthrough。
package main
import "fmt"
func main() {
// 1. 标准用法
day := "Monday"
switch day {
case "Saturday", "Sunday": // 一分支匹配多个值
fmt.Println("周末")
case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday":
fmt.Println("工作日")
default:
fmt.Println("无效输入")
}
// 2. 无表达式 switch(替代复杂的 if-else)
age := 18
switch {
case age < 18:
fmt.Println("未成年")
case age >= 18:
fmt.Println("成年")
}
}
3. 循环结构 for
Go 语言只有 for 这一种循环关键字,但它可以灵活变通,完美替代 while 和 do-while。
① 三段式循环(传统 for)
for i := 0; i < 5; i++ {
fmt.Println(i)
}
② 单条件循环(替代 while)
n := 1
for n < 5 {
n *= 2
}
③ 无限循环(替代 while(true))
for {
// 配合 break 退出
break
}
④ 遍历集合 for - range
用于遍历数组、切片、Map、字符串和 Channel:
nums := []int{10, 20, 30}
// 遍历 Slice:返回 index 和 value
for i, v := range nums {
fmt.Printf("索引: %d, 值: %d\n", i, v)
}
// 遍历 Map:返回 key 和 value
m := map[string]int{"a": 1, "b": 2}
for k, v := range m {
fmt.Printf("键: %s, 值: %d\n", k, v)
}
4. 跳转控制 break / continue / goto
break:中断并跳出当前的for、switch或select语句。continue:跳过当前循环的剩余代码,直接进入下一次循环。- 带标签的跳转(Label):
break和continue后面可以接标签,用于直接跳出多层嵌套循环。 goto:跳转到当前函数内指定的标签位置(需谨慎使用,避免破坏代码逻辑)。
package main
import "fmt"
func main() {
OuterLoop:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
if i == 1 && j == 1 {
break OuterLoop // 直接跳出外层循环
}
fmt.Printf("i: %d, j: %d\n", i, j)
}
}
}
5. 并发选择 select
select 是 Go 语言特有的流程控制语句,专门用来处理多路 Channel(通道)的非阻塞收发操作:
- 随机选择一个就绪的
case执行。 - 如果所有
case都阻塞,且写了default,则执行default;若无default,则当前 goroutine 阻塞等待。
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
time.Sleep(1 * time.Second)
ch1 <- "one"
}()
select {
case msg1 := <-ch1:
fmt.Println("收到:", msg1)
case msg2 := <-ch2:
fmt.Println("收到:", msg2)
case <-time.After(500 * time.Millisecond):
fmt.Println("超时退出")
}
}