一共缕、for
Go 只有一種循環(huán)結(jié)構(gòu)—— for 循環(huán)汇四。
基本的 for 循環(huán)包含三個(gè)由分號(hào)分開的組成部分:
- 初始化語句:在第一次循環(huán)執(zhí)行前被執(zhí)行
- 循環(huán)條件表達(dá)式:每輪迭代開始前被求值
- 后置語句:每輪迭代后被執(zhí)行
初始化語句一般是一個(gè)短變量聲明豆村,這里聲明的變量僅在整個(gè) for 循環(huán)語句可見。
如果條件表達(dá)式的值變?yōu)?false亩钟,那么迭代將終止焙蚓。
注意:不像 C,Java宪彩,或者 Javascript 等其他語言休讳,for 語句的三個(gè)組成部分 并不需要用括號(hào)括起來,但循環(huán)體必須用 { } 括起來尿孔。
package main
import "fmt"
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
}
循環(huán)初始化語句和后置語句都是可選的。
package main
import "fmt"
func main() {
sum := 1
for ; sum < 1000; {
sum += sum
}
fmt.Println(sum)
}
for 是 Go 的 “while”
基于此可以省略分號(hào):C 的 while
在 Go 中叫做 for 。
package main
import "fmt"
func main() {
sum := 1
for sum < 1000 {
sum += sum
}
fmt.Println(sum)
}
如果省略了循環(huán)條件活合,循環(huán)就不會(huì)結(jié)束雏婶,因此可以用更簡潔地形式表達(dá)死循環(huán)。
package main
func main() {
for {
}
}
二白指、if
就像 for
循環(huán)一樣留晚,Go 的 if
語句也不要求用 ( ) 將條件括起來,同時(shí)告嘲, { } 還是必須有的错维。
package main
import (
"fmt"
"math"
)
func sqrt(x float64) string {
if x < 0 {
return sqrt(-x) + "i"
}
return fmt.Sprint(math.Sqrt(x))
}
func main() {
fmt.Println(sqrt(2), sqrt(-4))
}
跟 for 一樣, if 語句可以在條件之前執(zhí)行一個(gè)簡單語句橄唬。
由這個(gè)語句定義的變量的作用域僅在 if 范圍之內(nèi)赋焕。
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
}
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
在 if 的便捷語句定義的變量同樣可以在任何對(duì)應(yīng)的 else 塊中使用。
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
} else {
fmt.Printf("%g >= %g\n", v, lim)
}
// 這里開始就不能使用 v 了
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
三仰楚、switch
除非以 fallthrough
語句結(jié)束隆判,否則分支會(huì)自動(dòng)終止。
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Print("Go runs on ")
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
// freebsd, openbsd,
// plan9, windows...
fmt.Printf("%s.", os)
}
}
switch 的執(zhí)行順序
switch
的條件從上到下的執(zhí)行僧界,當(dāng)匹配成功的時(shí)候停止侨嘀。
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("When's Saturday?")
today := time.Now().Weekday()
switch time.Saturday {
case today + 0:
fmt.Println("Today.")
case today + 1:
fmt.Println("Tomorrow.")
case today + 2:
fmt.Println("In two days.")
default:
fmt.Println("Too far away.")
}
}
沒有條件的 switch
沒有條件的 switch
同 switch true
一樣。
這一構(gòu)造使得可以用更清晰的形式來編寫長的 if-then-else 鏈捂襟。
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
語句會(huì)延遲函數(shù)的執(zhí)行直到上層函數(shù)返回。
延遲調(diào)用的參數(shù)會(huì)立刻生成葬荷,但是在上層函數(shù)返回前函數(shù)都不會(huì)被調(diào)用涨共。
package main
import "fmt"
func main() {
defer fmt.Println("world")
fmt.Println("hello")
}
結(jié)果為:
hello
world
4.1 defer 棧
延遲的函數(shù)調(diào)用被壓入一個(gè)棧中。當(dāng)函數(shù)返回時(shí)闯狱, 會(huì)按照后進(jìn)先出的順序調(diào)用被延遲的函數(shù)調(diào)用煞赢。
package main
import "fmt"
func main() {
fmt.Println("counting")
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
fmt.Println("done")
}
結(jié)果為:
counting
done
9
8
7
6
5
4
3
2
1
0