2. 流程控制语句
2.1 for循环
首先明确Go 只有一种循环结构:for 循环。
2.1.1. 基本的 for 循环由三部分组成,它们用分号隔开:
markdown
for 初始化语句; 条件表达式; 后置语句{
循环体
}
规则:
1. 必须有语句条件表达式,
2. 有后置语句必须有初始化语句
3. ;可以代替语句,默认存在但不起作用
解释:
初始化语句:在第一次迭代前执行
条件表达式:在每次迭代前求值
后置语句:在每次迭代的结尾执行
初始化语句通常为一句短变量声明,该变量声明仅在 for 语句的作用域中可见。
一旦条件表达式的布尔值为 false,循环迭代就会终止。 代码如下:
css
package main
import "fmt"
func main() {
// 使用 for 循环遍历数字 1 到 5
for i := 1; i <= 5; i++ {
fmt.Println(i)
}
}
注意:和 C、Java、JavaScript 之类的语言不同,Go 的 for 语句后面的三个构成部分外没有小括号, 大括号 { } 则是必须的
2.1.2. for 循环的 range 形式可遍历切片或映射。
- 例子(直接看例子比较简单)
go
package main
import "fmt"
func main() {
// 定义切片
slice := []int{1, 2, 3, 4, 5}
// 使用 for 循环的 range 形式遍历切片
for index, value := range slice {
fmt.Printf("Index: %d, Value: %d\n", index, value)
}
// 定义映射
mapping := map[string]int{"one": 1, "two": 2, "three": 3, "four": 4, "five": 5}
// 使用 for 循环的 range 形式遍历映射
for key, value := range mapping {
fmt.Printf("Key: %s, Value: %d\n", key, value)
}
}
- 当使用 for 循环遍历切片时,每次迭代都会返回两个值。第一个值为当前元素的下标,第二个值为该下标所对应元素的一份副本(副本的意思在循环中修改val的值是没有意义的,需要拿着下标才能修改)。
go
package main
import "fmt"
func main() {
slice := []int{1, 2, 3, 4, 5}
// 使用 for 循环遍历切片
for index, value := range slice {
fmt.Printf("Index: %d, Value: %d\n", index, value)
// 修改切片中的元素
slice[index] = 10
//修改value的值是没有意义的
value = 1
fmt.Printf("Index: %d, Value: %d (after modification)\n", index, slice[index])
}
}
- 可以将下标或值赋予 _ 来忽略它。
go
for i, _ := range pow
for _, value := range pow
- 若你只需要索引,忽略第二个变量即可。(许多年的程序员也可能不知道)
go
for i := range pow
具体例子如下
go
package main
import "fmt"
func main() {
pow := make([]int, 10)
for i := range pow {
pow[i] = 1 << uint(i) // == 2**i
}
for _, value := range pow {
fmt.Printf("%d\n", value)
}
}
- for是可以无限循环的,想要结束无限循环的话只需要使用break即可
2.2 if判断
在 Go 语言中,if 语句用于根据条件来执行不同的代码块。它有两种形式:if-else 和 if-else if-else
2.2.1. if-else 形式:
ruby
if condition {
// 当条件为 true 时执行的代码块
} else {
// 当条件为 false 时执行的代码块
}
2.2.2. if-else if-else 形式:
ruby
if condition1 {
// 当条件 1 为 true 时执行的代码块
} else if condition2 {
// 当条件 2 为 true 时执行的代码块
} else {
// 当条件 1 和条件 2 都为 false 时执行的代码块
}
在这些形式中,condition 可以是任何布尔表达式。如果 condition 的结果为 true,则执行相应的代码块;否则,执行 else 后面的代码块。 以下是一个示例,演示如何使用 if 语句:
go
package main
import "fmt"
func main() {
age := 30
if age < 18 {
fmt.Println("你还未成年")
} else if age < 65 {
fmt.Println("你已经成年")
} else {
fmt.Println("你已经老年")
}
}
在这个示例中,根据变量 age 的值来判断一个人的年龄阶段,并输出相应的信息。
2.3 switch
在 Go 语言中,switch 语句用于基于不同条件执行不同的操作。它允许你根据一个表达式的值,选择不同的执行路径。
2.3.1. switch 语句的基本语法如下:
arduino
switch expression {
case value1:
// 当表达式的值等于 value1 时执行的操作
...
case value2:
// 当表达式的值等于 value2 时执行的操作
...
case value3:
// 当表达式的值等于 value3 时执行的操作
...
default:
// 当表达式的值不匹配任何 case 时执行的操作
...
}
其中,expression 是一个变量或表达式,value1、value2 等是与 expression 可能匹配的常量值。如果 expression 的值与某个 case 后面的常量值相等,就会执行相应的代码块。如果没有匹配的 case,则执行 default 后面的代码块。
2.3.2. 示例,演示如何使用 switch 语句:
go
package main
import "fmt"
func main() {
fruit := "apple"
switch fruit {
case "apple":
fmt.Println("苹果是一种美味的水果。")
case "banana":
fmt.Println("香蕉是一种美味的水果。")
case "orange":
fmt.Println("橙子是一种美味的水果。")
default:
fmt.Println("未知的水果。")
}
}
在这个示例中,根据变量 fruit 的值来执行不同的操作。如果 fruit 的值是 "apple",则打印出 "苹果是一种美味的水果。";如果是 "banana",则打印出 "香蕉是一种美味的水果。";如果是 "orange",则打印出 "橙子是一种美味的水果。";如果都不匹配,则打印出 "未知的水果。"。 需要注意的是,switch 语句中的 case 后面必须是常量或常量表达式,而且每个 case 必须是唯一的。 如果需要处理多个值,可以使用逗号分隔多个 case。
go
package main
import "fmt"
func main() {
fruit := "apple,banana,orange"
switch fruit {
case "apple", "banana", "orange":
fmt.Println("这些水果都是美味的。")
default:
fmt.Println("未知的水果。")
}
}
2.3.3. switch中的breath和fallthrough
switch 只执行一个case中的语句,所以不需要break, 其中fallthrough关键字,它用来执行下一个case的body的部分
go
package main
import "fmt"
func main() {
num := 4
switch num {
case 4:
fmt.Println("Case 4")
fallthrough
case 5:
fmt.Println("Case 5")
case 6:
fmt.Println("Case 6")
default:
fmt.Println("Default case")
}
}
上述代码会打印
sql
Case 4
Case 5
如果没有fallthrough的话,则打印
Case4
2.4. defer(推迟语句)
在 Go 语言中,defer 语句用于在函数返回之前延迟执行某些操作。它可以用于释放资源、关闭文件、进行清理工作等。
2.4.1 defer 语句的语法如下:
go
defer func()
你可以在函数内的任何位置使用 defer 语句来注册一个延迟执行的函数。当函数执行到 return 语句或达到函数的自然结束时,所有注册的 defer 函数会按照逆序依次执行。
2.4.2. 示例,演示了如何使用 defer 语句来释放资源:
go
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
// 延迟执行函数
defer fmt.Println("资源已释放")
// 生成随机数
r := rand.Intn(100)
fmt.Println("随机数:", r)
}
在这个示例中,使用 defer 语句注册了一个延迟执行的函数,然后,使用 rand.Intn(100) 函数生成一个随机数,并将其打印出来,最后会在函数返回之前执行延迟执行的函数并打印出 "资源已释放"。 值得注意的是在项目中建立全局连接(如mysql,grpc连接)时会使用这个延迟执行关闭函数。 此外在错误处理机制中也使用到了defer 包括gin框架中的洋葱模型也是通过defer实现的,因此博主认为defer更多的是概念方面的,上面具体的内容会在后面对应的模块相继推出