golang學習筆記(二):流程控制

歡迎訪問個人博客github!linux

今天我們把煩人的事情丟一丟,繼續來學習go的基礎知識。git

這篇文章記錄go語言的流程控制和更多類型。github

流程控制

for

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)
}

for 中的 while

此時你能夠去掉分號,由於 C 的 while 在 Go 中叫作 forip

package main

import "fmt"

func main() {
    sum := 1
    for sum < 1000 {
        sum += sum
    }
    fmt.Println(sum)
}

無限循環

省略循環條件變成無限循環作用域

package main

func main() {
    for {
    }
}

if

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))
}

if 的簡短語句

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

if 的簡短語句中聲明的變量一樣能夠在任何對應的 else 塊中使用。

(在 mainfmt.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

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 的求值順序

switch 的 case 語句從上到下順次執行,直到匹配成功時中止。

(例如,

switch i {
case 0:
case f():
}

i==0f 不會被調用。)

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 同樣。

這種形式能將一長串 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 棧

推遲的函數調用會被壓入一個棧中。當外層函數返回時,被推遲的函數會按照後進先出的順序調用。

package main

import "fmt"

func main() {
    fmt.Println("counting")

    for i := 0; i < 10; i++ {
        defer fmt.Println(i)
    }

    fmt.Println("done")
}

歡迎訪問個人博客github!

相關文章
相關標籤/搜索