Go 入门 - 控制流
主要内容来自中文版的官方教程Go语言之旅
目的为总结要点
循环
Go 只有 for
循环
for
由三部分组成,用分号间隔开
- 初始化语句:在第一次迭代之前执行,通常为一句短变量声明(
i:=0
) - 条件表达式:在每次迭代之前求值,一旦条件表达式的值是
false
循环终止 - 后置语句:在每次迭代结束之后执行
for
语言没有小括号,大括号是必须的。
package main
import "fmt"
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
}
需要注意,for
语句中声明的变量是局部变量,下面这个例子中省略了后置语句
package main
import "fmt"
func main() {
var sum int = 1
for sum := 10; sum < 1000; {
sum += sum //在这里改变sum并不会影响其他的外层的sum
fmt.Println(sum)
}
fmt.Println(sum)
}
// output 40 80 160 640 1280 1
将所有的分号去掉,可以直接当做while来使用,下面这个例子中省略了初始化语句和后置语句
package main
import "fmt"
func main() {
sum := 1
for sum < 1000 {
sum += sum
fmt.Println(sum)
}
fmt.Println(sum)
}
// output 2 4 8 16 32 64 128 256 512 1024 1024
如果只有for 那么代表无限循环,下面这个例子中省略了所有语句
package main
func main() {
for {
}
}
分支
Go也用if
来表示分支,表达式无需小括号,必须大括号
func sqrt(x float64) string {
if x < 0 {
return sqrt(-x) + "i"
}
return fmt.Sprint(math.Sqrt(x))
}
和for
类似,if
在条件表达式之前可以执行一个简单语句,该语句生命的变量作用于仅在if
之内
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
fmt.Println(v)
return v // 如果v 小于上界,返回v
} else {
fmt.Printf("%g >= %g\n", v, lim)
}
// 这里开始就不能使用 v 了
return lim // 否则,返回上界
}
switch
和C
不同,Go
之运行选定的case,不会接着运行之后所有的case,相当于自动提供了break
。switch的case语句从上到下顺序求值,知道匹配成功为止
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Print("Go runs on ")
switch os := runtime.GOOS; os { // os 的取值不需要为常量,也不需要为整数
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
// freebsd, openbsd,
// plan9, windows...
fmt.Printf("%s.", os)
}
}
没有条件的switch默认为switch true
,比如
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("Good morning!")
case t.Hour() < 17:
fmt.Println("Good afternoon.")
default:
fmt.Println("Good evening.")
}
}
defer
defer
是一个关键字,以这个关键字开始的语句会将函数推迟到外层函数返回之后执行。
package main
import "fmt"
func main() {
defer fmt.Println("world")
fmt.Println("hello")
}
//output:
//hello
//world
推迟调用的函数其参数会立即求值,但直到外层函数返回前该函数都不会被调用。推迟的函数调用会被压入一个栈中。当外层函数返回时,被推迟的函数会按照后进先出的顺序调用。
package main
import "fmt"
func main() {
fmt.Println("counting")
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
fmt.Println("done")
}
//output
//counting
//done
//9
//8
//7
//6
//5
//4
//3
//2
//1
//0