主要内容来自中文版的官方教程
目的为总结要点循环
Go 只有 for
循环
for
由三部分组成,用分号间隔开
- 初始化语句:在第一次迭代之前执行,通常为一句短变量声明(
i:=0
) - 条件表达式:在每次迭代之前求值,一旦条件表达式的值是
false
循环终止 - 后置语句:在每次迭代结束之后执行
for
语言没有小括号,大括号是必须的。
package mainimport "fmt"func main() { sum := 0 for i := 0; i < 10; i++ { sum += i }}
需要注意,for
语句中声明的变量是局部变量,下面这个例子中省略了后置语句
package mainimport "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 mainimport "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 mainfunc 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 mainimport ( "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 mainimport ( "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 mainimport "fmt"func main() { defer fmt.Println("world") fmt.Println("hello")}//output://hello//world
推迟调用的函数其参数会立即求值,但直到外层函数返回前该函数都不会被调用。推迟的函数调用会被压入一个栈中。当外层函数返回时,被推迟的函数会按照后进先出的顺序调用。
package mainimport "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