今天我們把煩人的事情丟一丟,繼續來學習go的基礎知識。git
這篇文章記錄go語言的流程控制和更多類型。github
Go 只有一種循環結構:for
循環。windows
基本的 for
循環由三部分組成,它們用分號隔開:函數
初始化語句一般爲一句短變量聲明,該變量聲明僅在 for
語句的做用域中可見。學習
一旦條件表達式的布爾值爲 false
,循環迭代就會終止。code
注意:和 C、Java、JavaScript 之類的語言不一樣,Go 的 for 語句後面的三個構成部分外沒有小括號, 大括號 { }
則是必須的blog
package main import "fmt" func main() { sum := 0 for i := 0; i < 10; i++ { sum += i } fmt.Println(sum) }
此時你能夠去掉分號,由於 C 的 while
在 Go 中叫作 for
。ip
package main import "fmt" func main() { sum := 1 for sum < 1000 { sum += sum } fmt.Println(sum) }
省略循環條件變成無限循環作用域
package main func main() { for { } }
Go 的 if
語句與 for
循環相似,表達式外無需小括號 ( )
,而大括號 { }
則是必須的。
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
語句能夠在條件表達式前執行一個簡單的語句。
該語句聲明的變量做用域僅在 if
以內。
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
的簡短語句中聲明的變量一樣能夠在任何對應的 else
塊中使用。
(在 main
的 fmt.Println
調用開始前,兩次對 pow
的調用均已執行並返回其各自的結果。)
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
是編寫一連串 if - else
語句的簡便方法。它運行第一個值等於條件表達式的 case 語句。
Go 的 switch 語句相似於 C、C++、Java、JavaScript 和 PHP 中的,不過 Go 只運行選定的 case,而非以後全部的 case。 實際上,Go 自動提供了在這些語言中每一個 case 後面所需的 break
語句。 除非以 fallthrough
語句結束,不然分支會自動終止。 Go 的另外一點重要的不一樣在於 switch 的 case 無需爲常量,且取值沒必要爲整數。
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.\n", os) } }
switch 的 case 語句從上到下順次執行,直到匹配成功時中止。
(例如,
switch i { case 0: case f(): }
在 i==0
時 f
不會被調用。)
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 true
同樣。
這種形式能將一長串 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.") } }
推遲的函數調用會被壓入一個棧中。當外層函數返回時,被推遲的函數會按照後進先出的順序調用。
package main import "fmt" func main() { fmt.Println("counting") for i := 0; i < 10; i++ { defer fmt.Println(i) } fmt.Println("done") }