循環(huán)語句
Go 只有一種循環(huán)結構——for 循環(huán)。
基本的 for 循環(huán)除了沒有了 ( ) 之外(甚至強制不能使用它們),看起來跟 C 或者 Java 中做的一樣,而 { } 是必須的。
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
}
// 結果:45
跟 C 或者 Java 中一樣,可以讓前置、后置語句為空。
func main() {
sum := 1
for sum < 1000 {
sum += sum
}
fmt.Println(sum)
}
// 結果:1024
如果省略了循環(huán)條件,循環(huán)就不會結束,因此可以用更簡潔地形式表達死循環(huán)。
func main() {
for {
}
}
條件語句 if
if 語句除了沒有了 ( ) 之外(甚至強制不能使用它們),看起來跟 C 或者 Java 中的一樣,注意 { } 是必須的。
func sex(man bool) string {
if man {
return fmt.Sprint("you are a man")
}
return fmt.Sprint("you are a woman")
}
func main() {
man := true
sex(man)
fmt.Println(sex(man))
}
// 結果:you are a man
if 的便捷語句
跟 for 一樣,if 語句可以在條件之前執(zhí)行一個簡單的語句。
由這個語句定義的變量的作用域僅在 if 范圍之內。
func pow(x, n, lim float64) float64 {
// pow 為計算 x 的 n 次冪
if v := math.Pow(x, n); v < lim {
return v
}
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
// 結果:9 20
if 和 else
在 if 的便捷語句定義的變量同樣可以在任何對應的 else 塊中使用。
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),
)
}
// 結果
/*
27 >= 20
9 20
*/
用牛頓法實現(xiàn)開方函數(shù)
在這個例子中,牛頓法是通過選擇一個初始點 z 然后重復這一過程求 Sqrt(x) 的近似值:

為了做到這個,只需要重復計算 10 次,并且觀察不同的值(1,2,3,……)是如何逐步逼近結果的。
func sqrt(x float64) float64 {
z := 1.0
for v := 0; v < 10; v++{
z = z - (z * z - x)/(2 * z)
fmt.Println(z)
}
return z
}
func main() {
fmt.Println(sqrt(4))
fmt.Println(math.Sqrt(4))
}
// 結果
/*
2.5
2.05
2.000609756097561
2.0000000929222947
2.000000000000002
2
2
2
2
2
2
go math結果:2
*/
switch
一個結構體(struct)就是一個字段的集合。
除非以 fallthrough 語句結束,否則分支會自動終止。
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)
}
}
// 結果:Go runs on OS X.
// 注:當前實驗機器為Macbook
switch 的執(zhí)行順序
switch 的條件從上到下的執(zhí)行,當匹配成功的時候停止。
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.")
}
}
// 結果:
// When's Saturday?
// Too far away.
// 注:當前實驗時間周二
沒有條件的 switch
沒有條件的 switch 同 switch true 一樣。
這一構造使得可以用更清晰的形式來編寫長的 if-then-else 鏈。
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.")
}
}
// 結果:Good afternoon.
// 注:當前時間下午一點
defer
defer 語句會延遲函數(shù)的執(zhí)行直到上層函數(shù)返回。
延遲調用的參數(shù)會立刻生成,但是在上層函數(shù)返回前函數(shù)都不會被調用
func main() {
defer fmt.Println("world")
fmt.Println("hello")
}
/*
hello
world
*/
defer 棧
延遲的函數(shù)調用被壓入一個棧中。當函數(shù)返回時, 會按照后進先出的順序調用被延遲的函數(shù)調用
func main() {
fmt.Println("counting")
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
fmt.Println("done")
}
/*
counting
done
9
8
7
6
5
4
3
2
1
0
*/