Go语言的分支循环语句和大多数语言使用起来稍有区别,Go的语法乍一看可能确实比较怪异,但总体思想还是一样的,这篇笔记我们介绍相关的语法。
下面是计算1-100
整数的和,Go语言中,for循环没有括号,而且定义循环变量只能用:=
的形式。
package main
import "fmt"
func main() {
var sum = 0
for i := 1; i <= 100; i++ {
sum += i
}
fmt.Println(sum)
}
Go语言中for range
用法类似其它语言的for each
语法,可以很方便的循环一个数组,不过不要和Python中的range
函数弄混淆。
package main
import "fmt"
func main() {
var arr = []string{"tom", "jerry", "lucy"}
for index, name := range arr {
fmt.Println(index, name)
}
}
for
语句中声明了两个变量,它们名字是自己任意取的,第一个表示对应元素的数组索引,索引从0开始,第二个是数组元素值。如果只需要索引,第二个变量可以省略。如果不需要索引,可用一个下划线_
代替原本的变量。
for _, name := range arr { ... }
Go语言没有while
关键字,而是使用for
实现相同的写法。下面例子代码用这种写法实现求1-100
整数的和。
package main
import "fmt"
func main() {
var sum = 0
var i = 1
for i <= 100 {
sum += i
i++
}
fmt.Println(sum)
}
如果我们要写一个无限循环,不加任何条件即可。
for {
// ... 循环逻辑
}
if
写法也是没有括号的,语法和大多数语言相同。
package main
import "fmt"
func main() {
var i = 1
var j = 2
if i < j {
fmt.Println(j)
} else {
fmt.Println(i)
}
}
在if
条件内部可以加一条语句,用于对判断条件进行一些处理,非常方便。
if sum := i + j; a < sum { ... }
这个写法在错误处理时很常用,也推荐这样写,下面是一个例子。
if err := conn.Close(); err != nil {
// ... 错误处理逻辑
}
Go语言中的switch
终于不用写break
了。
package main
import "fmt"
func main() {
var current = 2
switch current {
case 1:
fmt.Println("Good morning!")
case 2:
fmt.Println("Good afternoon!")
case 3:
fmt.Println("Good night!")
default:
fmt.Println("Unrecognized time")
}
}
Go语言还支持另一种switch
,这种需要在case
后面直接写明判断条件。
package main
import "fmt"
func main() {
var current = 7
switch {
case current <= 7:
fmt.Println("Good morning!")
case current <= 17:
fmt.Println("Good afternoon!")
case current <= 23:
fmt.Println("Good night!")
default:
fmt.Println("Unrecognized time")
}
}
Go语言支持一个比较特别的defer
语句,它用于注册延迟调用代码,指定的语句能够在函数体代码执行结束后执行。我们学过汇编都知道函数返回是一个栈操作,defer
其实就是在函数返回地址入栈之前,先将defer
语句对应的执行流程地址入栈,如果defer
语句有多个,它们会按照出栈顺序执行。defer
语句常用于资源清理、记录日志等逻辑。
package main
import "fmt"
func test() {
defer fmt.Println("func test defer1")
defer fmt.Println("func test defer2")
fmt.Println("func test return")
}
func main() {
test()
fmt.Println("func main return")
}
执行结果:
func test return
func test defer2
func test defer1
func main return
有时defer
逻辑可能比较复杂,包含不止一行代码,此时我们可以使用defer
调用函数或是编写一个自执行函数,下面是一个例子。
defer func(conn net.Conn) {
if err := conn.Close(); err != nil {
fmt.Println(err)
return
}
}(conn)